Je trouve moi-même à l'aide de C++11 de plus en plus tardivement, et où j'aurais été en utilisant des itérateurs dans le passé, je suis maintenant à l'aide de gamme à base de boucles à chaque fois que possible:
std::vector<int> coll(10);
std::generate(coll.begin(), coll.end(), []() { return rand(); } );
C++03:
for (std::vector<int>::const_iterator it = coll.begin(); it != coll.end(); ++it) {
foo_func(*it);
}
C++11:
for (auto e : coll) { foo_func(e); }
Mais que faire si la collecte type d'élément est un paramètre du modèle? foo_func()
sera probablement surchargé de passe complexe (= cher pour copier) de type const référence, simples et par valeur:
foo_func(const BigType& e) { ... };
foo_func(int e) { ... };
Je n'ai pas donné cette pensée bien alors que j'ai été en utilisant le C++03-style code ci-dessus. Je voudrais réitérer la même manière, et depuis référence à un const_iterator produit const référence, tout allait bien. Mais en utilisant le C++11 basés sur la plage pour la boucle, j'ai besoin d'utiliser un const de référence de la variable de boucle d'obtenir le même comportement:
for (const auto& e : coll) { foo_func(e); }
Et tout à coup je n'étais pas sûr, si ce ne serait pas inutile d'introduire des instructions de montage si auto
était un type simple (comme un behind-the-scene pointeur de mettre en œuvre la référence).
Mais la compilation d'un exemple d'application a confirmé qu'il n'y a pas de frais généraux pour les types simples, et que cela semble être la façon générique à l'utilisation de la gamme, à base de boucles dans les modèles. Si ce n'avait pas été le cas, boost::call_traits::param_type aurait été le chemin à parcourir.
Question: existe-il des garanties dans la norme?
(Je me rends compte que le problème n'est pas vraiment liée à la gamme de base pour les boucles. Il est également présent lors de l'utilisation de const_iterators.)