移動専用型によるベクトルの初期化
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()}; }
ただし、このコードはコンパイル中にエラーを引き起こします。 GCC 4.7 では、std::unique_ptr がコピーをサポートしていないため、コンパイラは初期化中にポインタのコピーを作成しようとします。
GCC の動作
GCC のコピーの試行ポインタは現在の C 標準では正しいと考えられますが、C 標準ではリスト初期化シナリオに明示的に対処していません。 unique_ptr.
代替の初期化方法
移動のみの型でベクトルを適切に初期化するには、次のアプローチを使用できます。
イテレータの使用:
このアプローチこれには、初期化子リストの移動反復子を作成し、それをベクトルのコンストラクターに渡すことが含まれます:
#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))}; }
rref_wrapper の使用:
この手法では、移動参照用の一時ストレージ:
#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()); }
以上がC で移動のみの型を使用してベクトルを正しく初期化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。