Initialisation de vecteur avec des types à déplacement uniquement
Considérez le code suivant, qui vise à initialiser un vecteur avec des instances std::unique_ptr :
#include <vector> #include <memory> int main() { using move_only = std::unique_ptr<int>; std::vector<move_only> v{move_only(), move_only(), move_only()}; }
Cependant, ce code déclenche une erreur lors de la compilation dans GCC 4.7, car std::unique_ptr ne prend pas en charge la copie et le compilateur tente de créer des copies des pointeurs lors de l'initialisation.
Comportement de GCC
La tentative de GCC de copier les pointeurs peut être considéré comme correct selon la norme C actuelle, qui ne traite pas explicitement des scénarios d'initialisation de liste pour les types de déplacement uniquement comme unique_ptr.
Méthodes d'initialisation alternatives
Pour initialiser correctement un vecteur avec des types de déplacement uniquement, on peut utiliser les approches suivantes :
Utilisation d'itérateurs :
Cette approche consiste à créer un itérateur de déplacement pour la liste d'initialisation et à transmettre au constructeur du vecteur :
#include <iterator> #include <vector> #include <memory> int main() { using move_only = std::unique_ptr<int>; move_only init[] = {move_only(), move_only(), move_only()}; std::vector<move_only> v{std::make_move_iterator(std::begin(init)), std::make_move_iterator(std::end(init))}; }
Utilisation de rref_wrapper :
Cette technique utilise un type d'assistance qui fournit un stockage temporaire pour les références de déplacement :
#include <utility> #include <type_traits> template<class T> struct rref_wrapper { explicit rref_wrapper(T&& v) : _val(std::move(v)) {} explicit operator T() const { return T{std::move(_val)}; } private: T&& _val; }; template<class T> typename std::enable_if<!std::is_lvalue_reference<T>::value, rref_wrapper<T>&>::type rref(T&& v) { return rref_wrapper<T>(std::move(v)); } template<class T> void rref(T&) = delete; int main() { using move_only = std::unique_ptr<int>; std::initializer_list<rref_wrapper<move_only>> il{rref(move_only()), rref(move_only()), rref(move_only())}; std::vector<move_only> v(il.begin(), il.end()); }
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!