移動のみ型のベクトルでリスト初期化を使用できますか?
list-initialization 構文では、GCC は unique_pointers をベクトルにコピーしようとします。この動作は、 unique_ptrs がコピー可能ではないという事実に起因しています。
ポインタをコピーしようとする GCC は正しいですか?
この場合の GCC の動作は正しくありません。 unique_ptrs のベクトルは、ポインターをコピーして構築することはできません。代わりに、移動セマンティクスを使用する必要があります。
代替解決策
移動専用型のベクトルを適切に初期化するには、std::make_move_iterator を使用して指定された要素を移動する反復子を作成します。 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))}; }
追加のアプローチ
それほど単純ではありませんが、std::enable_if とヘルパー構造体 rref_wrapper を使用して move のベクトルを構築する別の方法もあります。 -only タイプ:
#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;
このヘルパーを使用すると、ベクターは次のことができます。
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());
このアプローチでは std::enable_if を利用して、rref が一時的にのみ使用できるようにし、潜在的な誤用を防ぎます。
以上がリスト初期化は C の移動専用型のベクトルを正しく処理できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。