可以实现仅移动类型的向量初始化吗?
尝试使用唯一指针(移动)初始化向量时会出现问题-仅限类型。当遇到这样的代码时:
#include <vector> #include <memory> 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 复制指针的意图是正确的。但是,它使用的方法(从初始值设定项列表进行复制)会触发已删除的复制构造函数。
使用 Make Move Iterator 的替代解决方案
处理仅移动类型向量初始化,首选方法涉及利用 make move 迭代器:
#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))}; }
从 make move 获得的迭代器迭代器在解引用时促进元素的移动,解决复制问题。
使用模板包装器的替代解决方案
另一种方法涉及使用具有右值引用语义的模板包装器:
// Helper type for converting rvalues to lvalues 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; }; // Helper function to convert rvalues to rref_wrappers 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)); } // Helper function to delete lvalue references 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());
以上是如何在 C 中初始化具有仅移动类型的向量?的详细内容。更多信息请关注PHP中文网其他相关文章!