Question Règles générales de passage / renvoi de la référence du tableau (et non du 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 retourner la référence d'un tableau à partir d'une fonction?

Je veux retourner un tableau de types suivants d'une fonction:

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

M et N est connu au moment de la compilation!

Quelles sont les règles générales pour transmettre et renvoyer la référence à 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 a commenté: int (*a)[N] n'est pas un tableau, c'est un pointeur vers un tableau.

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


32
2018-03-22 23:03


origine


Réponses:


Si vous voulez renvoyer une référence à un tableau à partir d'une fonction, la déclaration devrait ressembler à 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 ressemble à la déclaration d'une variable qui fait référence à un tableau - mais seulement que le nom de la fonction est suivi par (), qui peut contenir des déclarations de paramètres:

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

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

typedef int array_t[10];

array_t& f() {
   return global;
}

Si vous voulez qu'il soit 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;
}

Pointeurs aux tableaux fonctionnent de la même façon, mais seulement qu'ils utilisent * au lieu de &.


41
2018-03-22 23:12



Vous ne pouvez pas renvoyer 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
2018-03-22 23:07



Avec la syntaxe du type de retour de 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
2017-08-06 20:04



Comme Erik a mentionné, vous ne pouvez pas retourner un tableau d'une fonction. Vous pouvez retourner un pointeur ou une référence, bien que la syntaxe soit très velue:

// 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 recommande fortement de créer 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
2018-03-22 23:14



En plus de la réponse précise de sth, voici comment déclarer une classe avec une méthode constante renvoyant une référence de tableau:

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

1
2018-01-27 13:41



Ceci est marqué C ++, donc je vais suggérer que la façon de retourner un tableau en C ++ est de renvoyer un std::vector et n'essayez pas de tromperie avec les tableaux C (qui ne doivent être utilisés que dans des scénarios soigneusement sélectionnés en code C ++).

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


0
2018-03-22 23:23