web-dev-qa-db-fra.com

Règles générales de passage/retour de référence de tableau (pas de pointeur) vers/depuis une fonction?

Nous pouvons passer la référence d'un tableau à une fonction comme:

void f(int (&a)[5]);

int x[5];
f(x);     //okay
int y[6];
f(y);     //error - type of y is not `int (&)[5]`.

Ou mieux encore, nous pouvons écrire un modèle de fonction:

template<size_t N>
void f(int (&a)[N]); //N is size of the array!

int x[5];
f(x);     //okay - N becomes 5
int y[6];
f(y);     //okay - N becomes 6

Maintenant ma question est, comment renvoyer la référence d'un tableau d'une fonction?

Je veux renvoyer un tableau des types suivants d'une fonction:

int a[N];
int a[M][N];
int (*a)[N];
int (*a)[M][N];

M et N sont connus au moment de la compilation!

Quelles sont les règles générales pour passer et renvoyer une référence au moment de la compilation d'un tableau vers et depuis une fonction? Comment pouvons-nous passer la référence d'un tableau de type int (*a)[M][N] à une fonction?

MODIFIER:

Adam commenté: int (*a)[N] n'est pas un tableau, c'est un pointeur sur un tableau.

Oui. Mais une dimension est connue au moment de la compilation! Comment pouvons-nous transmettre cette information connue lors de la compilation à une fonction?

33
Nawaz

Si vous voulez renvoyer une référence à un tableau à partir d'une fonction, la déclaration ressemblerait à ceci:

// an array
int global[10];

// function returning a reference to an array
int (&f())[10] {
   return global;
}

La déclaration d'une fonction renvoyant une référence à un tableau a le même aspect que la déclaration d'une variable qui est une référence à un tableau - le nom de la fonction étant suivi de (), qui peut contenir des déclarations de paramètre:

int (&variable)[1][2];
int (&functionA())[1][2];
int (&functionB(int param))[1][2];

De telles déclarations peuvent être rendues beaucoup plus claires en utilisant un typedef:

typedef int array_t[10];

array_t& f() {
   return global;
}

Si vous voulez que cela devienne vraiment déroutant, vous pouvez déclarer une fonction qui prend une référence à un tableau et renvoie également une telle référence:

template<int N, int M>
int (&f(int (&param)[M][N]))[M][N] {
   return param;
}

Les pointeurs sur les tableaux fonctionnent de la même manière, sauf qu’ils utilisent * au lieu de &.

41
sth

Avec la syntaxe de type retour de fin C++ 11, vous pouvez également écrire:

auto foo () -> int (&)[3]
{
    static int some_array[3]; // doesn't have to be declared here
    return some_array; // return a reference to the array.
}
9
Thomas Eding

Vous ne pouvez pas retourner un tableau à partir d'une fonction.

8.3.5/6:

Les fonctions ne doivent pas avoir de type de retour de type tableau ou fonction, bien que ils peuvent avoir un type de retour de type pointeur ou référence à de telles choses.

EDIT: Vous allez adorer la syntaxe:

int (&bar()) [5] {
  static int x[5];
  return x;
}


int (* & bar()) [6][10] {
    static int x[6][10];
    static int (*y)[6][10] = &x;
    return y;
}
// Note - this returns a reference to a pointer to a 2d array, not exactly what you wanted.
9
Erik

Comme Erik a mentionné , vous ne pouvez pas retourner un tableau à partir d'une fonction. Vous pouvez renvoyer un pointeur ou une référence, bien que la syntaxe soit assez complexe:

// foo returns a pointer to an array 10 of int
int (*foo(float arg1, char arg2))[10] { ... }

// bar returns a reference to an array 10 of int
int (&foo(float arg1, char arg2))[10] { ... }

Je vous recommande fortement de faire un typedef pour le type de tableau:

// IntArray10 is an alias for "array 10 of int"
typedef int IntArray10[10];

// Equivalent to the preceding definitions
IntArray10 *foo(float arg1, char arg2) { ... }
IntArray10 &bar(float arg1, char arg2) { ... }
3
Adam Rosenfield

En complément de la réponse fine par chah, voici comment déclarer une classe avec une méthode constante renvoyant une référence à un tableau:

class MyClass
{
public:
    const int (&getIntArray() const)[10];
};
1
Richard Struben

Ceci est étiqueté C++, je vais donc suggérer que la façon de renvoyer un tableau en C++ consiste à renvoyer un std::vector et de ne pas tenter la moindre astuce avec C-arrays (à utiliser uniquement dans des scénarios soigneusement sélectionnés en code C++).

Comme d'autres réponses l'ont noté, vous ne pouvez pas renvoyer de tableaux C à partir de fonctions.

0
Mark B