C++ passe un tableau par référence

Est-ce autorisé à passer un tableau par référence ?

 void foo(double& *bar) 

Semble que mon compilateur dit non. Pourquoi? Quelle est la bonne façon de passer un tableau de référence? Ou un travail autour? J'ai un argument de tableau Que ma méthode devrait Modifier et que je devrais récupérer par la suite. Alternativement, je pourrais faire de ce tableau un membre de classe, ce qui fonctionne bien, mais il présente de nombreux inconvénients pour une autre partie de mon code (que je voudrais éviter).

Merci et cordialement.

47
demandé sur BugShotGG 2012-04-04 13:00:16

6 réponses

Les tableaux ne peuvent être passés que par référence, en fait:

void foo(double (&bar)[10])
{
}

Cela vous empêche de faire des choses comme:

double arr[20];
foo(arr); // won't compile

Pour pouvoir passer un tableau de taille arbitraire à foo, Faites - en un modèle et capturez la taille du tableau au moment de la compilation:

template<typename T, size_t N>
void foo(T (&bar)[N])
{
    // use N here
}

, Vous devriez sérieusement envisager d'utiliser std::vector, ou si vous avez un compilateur qui prend en charge le c++11, std::array.

84
répondu jrok 2016-02-18 21:41:20

Oui, mais lorsque l'argument correspondant à une référence, le tableau implicite à le pointeur n'est pas automatique, donc vous avez besoin de quelque chose comme:

void foo( double (&array)[42] );

Ou

void foo( double (&array)[] );

Sachez cependant que lors de la correspondance, double [42] et double [] sont types distincts. Si vous avez un tableau d'une dimension inconnue, il faites correspondre le second, mais pas le premier, et si vous avez un tableau avec 42 éléments, il correspondra au premier mais pas au second . (Le dernier est, IMHO, très contre-intuitif.)

Dans dans le second cas, vous devrez également passer la dimension, puisque il n'y a aucun moyen de le récupérer une fois que vous êtes à l'intérieur de la fonction.

9
répondu James Kanze 2015-08-25 13:23:03

Si vous souhaitez modifier uniquement les éléments:

void foo(double *bar);

Est suffisant.

Si vous voulez modifier l'adresse à (par exemple: realloc), mais cela ne fonctionne pas pour les tableaux:

void foo(double *&bar);

Est la forme correcte.

5
répondu Naszta 2014-06-17 21:06:26

Comme vous utilisez C++, la suggestion obligatoire qui manque encore ici est d'utiliser std::vector<double>.

Vous pouvez facilement le passer par référence:

void foo(std::vector<double>& bar) {}

Et si vous avez le support C++11, jetez également un oeil à std::array.

Pour référence:

5
répondu moooeeeep 2016-06-09 11:52:41

Comme le dit l'autre réponse, mettez le & après le *.

Cela soulève un point intéressant qui peut parfois être déroutant: les types doivent être lus de droite à gauche. Par exemple, il s'agit (à partir du * le plus à droite) d'un pointeur vers un pointeur constant vers un int.

int * const *x;

Ce que vous avez écrit serait donc un pointeur vers une référence, ce qui n'est pas possible.

1
répondu parkovski 2012-04-04 09:07:22

8.3.5.8 si le type d'un paramètre inclut un type de la forme "pointeur vers un tableau de limite inconnue de T" ou " référence au tableau de limite inconnue de T, " le programme est mal formé

1
répondu Kirilodius 2014-07-18 15:05:16