이동 전용 유형의 벡터와 함께 목록 초기화를 사용할 수 있나요?
목록 초기화 구문에서 GCC는 고유 포인터를 벡터에 복사하려고 시도합니다. 이 동작은 Unique_ptrs를 복사할 수 없다는 사실에서 비롯됩니다.
포인터 복사 시도에서 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!