Puis-je déplacer des éléments de std::initializer_list ?
Lorsque j'utilise std::initializer_list, il est logique de croire que l'on peut déplacer des éléments en sortir. Cependant, le code suivant démontre le contraire :
#include <initializer_list> #include <utility> template<typename T> void foo(std::initializer_list<T> list) { for (auto it = list.begin(); it != list.end(); ++it) { bar(std::move(*it)); // Safe? } }
Contrairement aux attentes, tenter de déplacer des éléments hors de std::initializer_list entraîne plutôt des copies. Cela est dû à la nature unique de std::intializer_list, qui nécessite une gestion spéciale du compilateur et n'a pas la sémantique de valeur des conteneurs typiques.
Le problème réside dans le type de retour de start() et end() pour std. ::initializer_list, qui est const T . Par conséquent, l'expression 'std::move(it)' produit une référence rvalue immuable (T const &&&), qui ne peut pas être efficacement déplacée. Il se lie simplement à un paramètre de fonction de type T const & parce que les rvalues se lient aux références const lvalue, ce qui entraîne une sémantique de copie.
Ce comportement peut sembler contre-intuitif, mais il permet au compilateur de potentiellement faire de la liste initializer_list un élément statiquement- constante initialisée. Néanmoins, cela introduit une incohérence dans laquelle l'utilisateur ne sait pas si le résultat de begin() et end() est const ou mutable.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!