>백엔드 개발 >C++ >목록 초기화가 C에서 이동 전용 유형의 벡터를 올바르게 처리할 수 있습니까?

목록 초기화가 C에서 이동 전용 유형의 벡터를 올바르게 처리할 수 있습니까?

DDD
DDD원래의
2024-12-24 16:41:14922검색

Can List-Initialization Correctly Handle Vectors of Move-Only Types in C  ?

이동 전용 유형의 벡터와 함께 목록 초기화를 사용할 수 있나요?

목록 초기화 구문에서 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&amp;&amp; v)
    : _val(std::move(v)) {}

  explicit operator T() const{
    return T{ std::move(_val) };
  }

private:
  T&amp;&amp; _val;
};

// only usable on temporaries
template<class T>
typename std::enable_if<
  !std::is_lvalue_reference<T>::value,
  rref_wrapper<T>
>::type rref(T&amp;&amp; v){
  return rref_wrapper<T>(std::move(v));
}

// lvalue reference can go away
template<class T>
void rref(T&amp;) = 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.