Heim >Backend-Entwicklung >C++ >Kann die Listeninitialisierung Vektoren von Nur-Verschiebungs-Typen in C korrekt verarbeiten?
Kann die Listeninitialisierung mit einem Vektor von Nur-Verschiebungs-Typen verwendet werden?
Bei der Initialisierung eines Vektors mit Nur-Verschiebungs-Typen mithilfe von Mit der Listeninitialisierungssyntax versucht GCC, die Unique_Pointer in den Vektor zu kopieren. Dieses Verhalten ist auf die Tatsache zurückzuführen, dass unique_ptrs nicht kopierbar sind.
Ist GCC korrekt beim Versuch, Zeiger zu kopieren?
Das Verhalten von GCC ist in diesem Fall nicht korrekt. Ein Vektor von unique_ptrs kann nicht durch Kopieren der Zeiger erstellt werden; Stattdessen muss die Bewegungssemantik verwendet werden.
Alternative Lösung
Um einen Vektor von Nur-Verschiebungstypen ordnungsgemäß zu initialisieren, ist es notwendig, std::make_move_iterator zu verwenden Erstellen Sie Iteratoren, die die Elemente, auf die verwiesen wird, verschieben, wenn sie dereferenziert werden:
#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))}; }
Zusätzlich Ansatz
Eine andere Alternative, wenn auch nicht so einfach, besteht darin, std::enable_if und eine Hilfsstruktur rref_wrapper zu verwenden, um einen Vektor von Nur-Verschiebungstypen zu erstellen:
#include <utility> #include <type_traits> template<class T> struct rref_wrapper { // CAUTION - very volatile, use with care explicit rref_wrapper(T&& v) : _val(std::move(v)) {} explicit operator T() const{ return T{ std::move(_val) }; } private: T&& _val; }; // only usable on temporaries 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)); } // lvalue reference can go away template<class T> void rref(T&) = delete;
Verwenden Sie dies Helfer, der Vektor kann in zwei Schritten initialisiert werden:
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());
Dieser Ansatz nutzt std::enable_if, um sicherzustellen, dass rref nur auf temporären Dateien verwendet werden kann, um so möglichen Missbrauch zu verhindern.
Das obige ist der detaillierte Inhalt vonKann die Listeninitialisierung Vektoren von Nur-Verschiebungs-Typen in C korrekt verarbeiten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!