En C++ 11, je peux parcourir un conteneur de la manière suivante:
for(auto i : vec){
std::cout << i << std::endl;
}
Mais je sais que cela - inutilement, puisqu'il ne me faut que print les valeurs de vec
- crée une copie de (EDIT: chaque élément de) vec
, alors je pourrait faire:
for(auto &i : vec){
std::cout << i << std::endl;
}
Mais je veux m'assurer que les valeurs de vec
ne sont jamais modifiées et respectent const-correctness, ainsi je peux faire:
for(const auto &i : vec){
std::cout << i << std::endl;
}
Ma question est donc la suivante: si j’ai seulement besoin de regarder les valeurs d’un conteneur, la dernière boucle (const auto &i
) ne serait-elle pas toujours préférée en raison de l’efficacité accrue de ne pas disposer d’une copie supplémentaire de (EDIT: chaque élément de) vec
?
J'ai un programme que je développe dans lequel je songe à apporter ce changement, car l'efficacité y est essentielle (la raison pour laquelle j'utilise le C++ à la première place).
Oui. La même raison si vous ne lisez qu'un argument, vous définissez le paramètre const&
.
T // I'm copying this
T& // I'm modifying this
const T& // I'm reading this
Ce sont vos "valeurs par défaut". Lorsque T
est un type fondamental (intégré), vous revenez généralement à const T
(pas de référence) pour la lecture, car une copie est moins chère qu'un alias.
J'ai un programme que je développe dans lequel j'envisage de faire ce changement, car l'efficacité y est essentielle
Imaginez si votre vecteur contient des chaînes. Longues ficelles. 5000 longues ficelles. Copiez-les inutilement et vous vous retrouverez avec une boucle bien écrite qui est terriblement inefficace.
Assurez-vous que votre code suit votre intention. Si vous n'avez pas besoin d'une copie à l'intérieur de la boucle, n'en faites pas.
Utilisez une référence & comme suggéré ci-dessus, ou des itérateurs.