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.
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
.
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.
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.
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:
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.
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é