En lisant quelques exemples de boucles basées sur une plage, ils suggèrent deux façons principales 1 , 2 , 3 , 4
std::vector<MyClass> vec;
for (auto &x : vec)
{
// x is a reference to an item of vec
// We can change vec's items by changing x
}
ou
for (auto x : vec)
{
// Value of x is copied from an item of vec
// We can not change vec's items by changing x
}
Bien.
Lorsque nous n'avons pas besoin de changer les vec
éléments, l'OMI, les exemples suggèrent d'utiliser la deuxième version (par valeur). Pourquoi ils ne suggèrent pas quelque chose qui fait const
référence (au moins, je n'ai trouvé aucune suggestion directe):
for (auto const &x : vec) // <-- see const keyword
{
// x is a reference to an const item of vec
// We can not change vec's items by changing x
}
N'est-ce pas mieux? N'évite-t-il pas une copie redondante à chaque itération alors que c'est un const
?
const auto &x
équivaut à votre troisième choix.auto&&
lorsque vous ne voulez pas faire de copie inutile, et que vous vous souciez de la modifier ou non, et que vous voulez simplement travailler.const
à coup sûr. Cependant, que ce soitauto const &
ouauto const
peu de différence. Je choisiraisauto const &
juste d'être plus cohérent.Si vous avez un
std::vector<int>
oustd::vector<double>
, alors c'est très bien d'utiliserauto
(avec copie de valeur) au lieu deconst auto&
, car copier unint
ou undouble
est bon marché:Mais si vous avez un
std::vector<MyClass>
, oùMyClass
a une sémantique de copie non triviale (par exemplestd::string
, une classe personnalisée complexe, etc.), je suggère d'utiliserconst auto&
pour éviter les copies profondes :la source
Ensuite, ils donnent une fausse suggestion.
Parce qu'ils donnent une mauvaise suggestion :-) Ce que vous mentionnez est correct. Si vous voulez seulement observer un objet, il n'est pas nécessaire de créer une copie, et il n'est pas nécessaire d'avoir une non
const
référence à lui.ÉDITER:
Je vois que les références que vous liez fournissent toutes des exemples d'itération sur une plage de
int
valeurs ou un autre type de données fondamental. Dans ce cas, étant donné que la copie d'unint
n'est pas coûteuse, la création d'une copie équivaut essentiellement (sinon plus efficacement) à une observationconst &
.Ce n'est cependant pas le cas en général pour les types définis par l'utilisateur. Les UDT peuvent être coûteux à copier, et si vous n'avez pas de raison de créer une copie (telle que la modification de l'objet récupéré sans altérer l'original), il est préférable d'utiliser a
const &
.la source
Je vais être contraire ici et dire qu'il n'y a pas besoin d'
auto const &
une plage basée sur une boucle. Dites-moi si vous pensez que la fonction suivante est idiote (pas dans son but, mais dans la façon dont elle est écrite):Ici, l'auteur a créé une référence const
v
à utiliser pour toutes les opérations qui ne modifient pas v. C'est idiot, à mon avis, et le même argument peut être avancé pour utiliserauto const &
comme variable dans une plage basée sur boucle au lieuauto &
.la source
const_iterator
à une boucle for? Comment vous assurez-vous que vous ne modifiez pas les éléments d'origine d'un conteneur lorsque vous l'itérez?const_iterator
? Laissez-moi deviner, le conteneur sur lequel vous itérez estconst
. Mais pourquoi est-ceconst
pour commencer? Quelque part que vous utilisezconst
pour vous assurer de quoi?const
est comme les avantages de l'utilisation deprivate
/protected
in classes. Cela évite d'autres erreurs.v
, la mise en œuvre irait bien à l'OMI. Et si la boucle ne modifie jamais les objets qu'elle parcourt, il me semble juste d'avoir une référenceconst
. Je vois votre point cependant. Le mien est que la boucle représente une unité de code à peu près comme le fait la fonction, et dans cette unité, il n'y a aucune instruction qui doit modifier la valeur. Par conséquent, vous pouvez «étiqueter» l'unité entière commeconst
, comme vous le feriez avec uneconst
fonction membre.const &
que la plage est stupide, car vous avez écrit un exemple imaginaire non pertinent d'un programmeur imaginaire qui a fait quelque chose de stupide avec la qualification cv ? ... OK alors