>백엔드 개발 >C++ >C에서 이동 전용 유형을 사용하여 벡터를 어떻게 초기화할 수 있습니까?

C에서 이동 전용 유형을 사용하여 벡터를 어떻게 초기화할 수 있습니까?

Linda Hamilton
Linda Hamilton원래의
2025-01-01 08:55:09887검색

How Can I Initialize a Vector with Move-Only Types in C  ?

이동 전용 유형을 사용하여 벡터 초기화를 수행할 수 있습니까?

고유 포인터를 사용하여 벡터를 초기화하려고 할 때 문제가 발생합니다. -전용 유형. 다음과 같은 코드가 발생하면:

#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에서 얻은 반복자 반복자는 역참조 시 요소 이동을 용이하게 하여 복사 문제를 해결합니다.

템플릿 래퍼를 사용하는 대체 솔루션

또 다른 접근 방식은 rvalue 참조 의미 체계를 갖춘 템플릿 래퍼를 사용하는 것입니다.

// 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&amp;&amp; _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&amp;) = delete;

이 솔루션은 개념적으로 rvalue를 다음으로 변환하는 방법을 제공하지만 lvalue의 변동성 때문에 주의를 기울이는 것이 중요합니다. 두 단계 프로세스를 통해 보다 간결한 초기화를 수행할 수 있습니다.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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