web-dev-qa-db-fra.com

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

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

 void foo(double& *bar) 

Il semble que mon compilateur dit non. Pourquoi? Quelle est la bonne façon de passer un tableau par 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 après. Alternativement, je pourrais faire de ce tableau un membre de la classe, ce qui fonctionne bien, mais il présente de nombreux inconvénients pour d'autres parties de mon code (que j'aimerais éviter).

Merci et salutations.

60
kiriloff

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 supporte c ++ 11, std::array.

96
jrok

Oui, mais lorsque la correspondance d'argument pour une référence, le tableau implicite au pointeur n'est pas automatique, vous avez donc besoin de quelque chose comme:

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

ou

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

Sachez cependant que lors de la mise en correspondance, double [42] et double [] sont des types distincts. Si vous avez un tableau de dimension inconnue, il correspondra au second, mais pas au premier, et si vous avez un tableau de 42 éléments, il correspondra au premier mais pas au second. (Ce dernier est, à mon humble avis, très contre-intuitif.)

Dans le second cas, vous devrez également passer la dimension, car il n’est pas possible de la récupérer une fois que vous êtes dans la fonction.

13
James Kanze

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

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

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

Et si vous avez le support de C++ 11, regardez aussi std::array.

Pour référence:

6
moooeeeep

Si vous souhaitez modifier uniquement les éléments:

void foo(double *bar);

est assez.

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

void foo(double *&bar);

est la forme correcte.

6
Naszta

8.3.5.8 Si le type d'un paramètre comprend un type de la forme "pointeur sur le tableau de la borne inconnue de T" ou "référence au tableau de la borne inconnue de T", le programme est mal formé

3
Kirilodius

Comme 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, ceci est (à partir de la plus à droite *) un pointeur sur un pointeur constant sur un int.

int * const *x;

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

2
parkovski