Il s'agit d'une discussion intéressante. Il est clair que les tableaux de références sont carrément illégaux, mais je pense que la raison n'est pas aussi simple que de dire "ce ne sont pas des objets" ou "ils n'ont pas de taille". J'aimerais souligner que les tableaux eux-mêmes ne sont pas des objets à part entière en C/C++ - si vous n'êtes pas d'accord avec cela, essayez d'instancier des classes de modèles stl en utilisant un tableau comme paramètre de modèle de 'classe', et voyez ce qui se passe. Vous ne pouvez pas les retourner, les assigner, les passer comme paramètres. (un paramètre de tableau est traité comme un pointeur). Mais il est légal de créer des tableaux de tableaux. Les références ont une taille que le compilateur peut et doit calculer - vous ne pouvez pas utiliser sizeof() pour une référence, mais vous pouvez créer une structure ne contenant que des références. Elle aura une taille suffisante pour contenir tous les pointeurs qui implémentent les références. Vous ne pouvez pas instancier une telle structure sans initialiser tous ses membres :
struct mys {
int & a;
int & b;
int & c;
};
...
int ivar1, ivar2, arr[200];
mys my_refs = { ivar1, ivar2, arr[12] };
my_refs.a += 3 ; // add 3 to ivar1
En fait, vous pouvez ajouter cette ligne à la définition de la structure
struct mys {
...
int & operator[]( int i ) { return i==0?a : i==1? b : c; }
};
...et maintenant j'ai quelque chose qui ressemble BEAUCOUP à un tableau de refs :
int ivar1, ivar2, arr[200];
mys my_refs = { ivar1, ivar2, arr[12] };
my_refs[1] = my_refs[2] ; // copy arr[12] to ivar2
&my_refs[0]; // gives &my_refs.a == &ivar1
Maintenant, ce n'est pas un vrai tableau, c'est une surcharge d'opérateur ; il ne fera pas les choses que les tableaux font normalement comme sizeof(arr)/sizeof(arr[0]), par exemple. Mais il fait exactement ce que je veux qu'un tableau de références fasse, avec un C++ parfaitement légal. Sauf que (a) c'est une douleur à mettre en place pour plus de 3 ou 4 éléments, et (b) ça fait un calcul en utilisant un tas de ? : qui pourrait être fait en utilisant l'indexation (pas avec l'indexation normale de la sémantique de calcul des pointeurs en C, mais l'indexation quand même). J'aimerais voir un type 'tableau de références' très limité qui puisse réellement faire cela. C'est-à-dire qu'un tableau de références ne serait pas traité comme un tableau général de choses qui sont des références, mais plutôt comme un nouveau type de "tableau de référence" qui correspondrait effectivement à une classe générée en interne, similaire à celle ci-dessus (mais que vous pouvez malheureusement utiliser pour créer un tableau de référence). ne peut pas faire avec des modèles).
ceci pourrait probablement fonctionner, si vous n'êtes pas gêné par ce genre de choses : refondre '*this' en un tableau d'int * et retourner une référence faite à partir de l'un d'entre eux : (non recommandé, mais cela montre comment le bon 'tableau' fonctionnerait) :
int & operator[]( int i ) { return *(reinterpret_cast<int**>(this)[i]); }
1 votes
Même si le tableau était valide, y stocker une valeur brute de '8' ne fonctionnerait pas. Si vous faisiez "intlink value = 8 ;", cela mourrait horriblement, car cela se traduirait simplement par "const int & value = 8 ;". Une référence doit faire référence à une variable.
3 votes
intlink value = 8;
Cela fonctionne. Vérifiez si vous n'y croyez pas.7 votes
Comme le souligne Alexey, il est parfaitement valable de lier une rvalue à une référence const.
2 votes
Quoi n'a pas le travail est que
operator=
. Les références ne peuvent pas être réinitialisées. Si vous voulez vraiment une telle sémantique - bien que je n'aie pas personnellement trouvé de situation dans laquelle elle soit pratiquement utile - alorsstd::reference_wrapper
serait la meilleure façon de procéder, car elle stocke un pointeur mais fournit une référence de typeoperator
et hace permettre le réassortiment. Mais dans ce cas, je n'utiliserais qu'un pointeur !1 votes
L'opérateur= est privé et n'est pas implémenté. En C++11, il s'agit de =delete.
1 votes
@underscore_d - Dans ce contexte, le "=" effectue une initialisation, pas une affectation. Ce n'est donc pas le problème. Je ne suis pas sûr d'avoir vu une bonne justification pour le moment, en fait.
0 votes
@JimmyHartzell Bon point, merci. Je suis tellement habitué à C++11 maintenant que je ne reconnais souvent pas les vieux trucs !