Home >Backend Development >C++ >Can List-Initialization Correctly Handle Vectors of Move-Only Types in C ?
Can List-Initialization Be Used with a Vector of Move-Only Types?
When initializing a vector with move-only types using the list-initialization syntax, GCC tries to copy the unique_pointers into the vector. This behavior stems from the fact that unique_ptrs are not copyable.
Is GCC Correct in Attempting to Copy Pointers?
GCC's behavior in this case is not correct. A vector of unique_ptrs cannot be constructed by copying the pointers; instead, the move semantics must be used.
Alternative Solution
To properly initialize a vector of move-only types, it is necessary to use std::make_move_iterator to create iterators that move the pointed-to elements when dereferenced:
#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))}; }
Additional Approach
Another alternative, although not as straightforward, involves using std::enable_if and a helper struct rref_wrapper to construct a vector of move-only types:
#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;
Using this helper, the vector can be initialized in two steps:
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());
This approach utilizes std::enable_if to ensure that rref can only be used on temporaries, thereby preventing any potential misuse.
The above is the detailed content of Can List-Initialization Correctly Handle Vectors of Move-Only Types in C ?. For more information, please follow other related articles on the PHP Chinese website!