列表初始化可以與僅移動類型的向量一起使用嗎?
使用僅移動型別初始化向量時列表初始化語法中,GCC 嘗試將 unique_pointers 複製到向量中。此行為源自於 unique_ptr 不可複製的事實。
GCC 嘗試複製指標是否正確?
GCC 在這種情況下的行為不正確。 unique_ptrs 的向量不能透過複製指標來建構;相反,必須使用移動語意。
替代解決方案
要正確初始化僅移動類型的向量,有必要使用 std::make_move_iterator來建立迭代器來移動指向的元素取消引用:
#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來建構移動向量-僅限型別:
#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中文網其他相關文章!