unique_ptr을 벡터로 푸시 백 할 수없는 이유는 무엇입니까?


217

이 프로그램에 어떤 문제가 있습니까?

#include <memory>
#include <vector>

int main()
{
    std::vector<std::unique_ptr<int>> vec;

    int x(1);
    std::unique_ptr<int> ptr2x(&x);
    vec.push_back(ptr2x); //This tiny command has a vicious error.

    return 0;
}

오류:

In file included from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/mingw32/bits/c++allocator.h:34:0,
                 from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/allocator.h:48,
                 from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/memory:64,
                 from main.cpp:6:
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h: In member function 'void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::unique_ptr<int>, _Tp* = std::unique_ptr<int>*]':
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/stl_vector.h:745:6:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::unique_ptr<int>, _Alloc = std::allocator<std::unique_ptr<int> >, value_type = std::unique_ptr<int>]'
main.cpp:16:21:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h:207:7: error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_Deleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]'
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/ext/new_allocator.h:105:9: error: used here
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/vector:69:0,
                 from main.cpp:7:
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h: In member function 'void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::unique_ptr<int>&}, _Tp = std::unique_ptr<int>, _Alloc = std::allocator<std::unique_ptr<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::unique_ptr<int>*, std::vector<std::unique_ptr<int> > >, typename std::vector<_Tp, _Alloc>::_Base::_Tp_alloc_type::pointer = std::unique_ptr<int>*]':
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/stl_vector.h:749:4:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::unique_ptr<int>, _Alloc = std::allocator<std::unique_ptr<int> >, value_type = std::unique_ptr<int>]'
main.cpp:16:21:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h:207:7: error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_Deleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]'
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/vector.tcc:314:4: error: used here

답변:


328

당신은 이동해야합니다 unique_ptr:

vec.push_back(std::move(ptr2x));

unique_ptr단일 unique_ptr컨테이너에 보유 포인터의 소유권이 있음을 보장합니다 . 즉, unique_ptr두 개의 unique_ptr소유권을 가지기 때문에 사본을 만들 수 없으므로 이동 만 할 수 있습니다.

그러나 현재 사용중인 정보 unique_ptr가 올바르지 않습니다. 로컬 변수에 대한 포인터를 관리하는 데 사용할 수 없습니다. 지역 변수의 수명은 자동으로 관리됩니다. 지역 변수는 블록이 종료 될 때 (예 :이 경우 함수가 반환 될 때) 파기됩니다. 객체를 동적으로 할당해야합니다.

std::unique_ptr<int> ptr(new int(1));

12
하나만있을 수 있으므로 임시를 벡터에 직접 전달할 수도 있습니다 vec.push_back(std::unique_ptr<int>(new int(1)));. unique_ptr또한 사용자 정의 삭제기를 사용할 수 있지만 (아무것도하지 않음) 범위의 끝에서 로컬 변수의 주소가 유효하지 않은 것을 고려해야합니다.
UncleBens

18
다른 옵션은을 사용하는 것 emplace_back입니다. 예vec.emplace_back(new int(1));
deft_code

75
@deft_code : 아니요, 안전하지 않습니다. emplace_back작업 이 수행 될 수 있으며이 작업 이 수행되면 동적으로 할당 int된 유출이 발생합니다. 경험상 누수를 피하기 위해 모든 동적 할당은 명명 된 스마트 포인터가 소유해야합니다.
James McNellis

8
make_shared ()는 unique_ptr이 아닌 shared_ptr을 리턴합니다. 불행히도 C ++ 11에는 make_unique ()가 없습니다. 희망적으로 C ++ 14에서 수정 될 불행한 누락
cdmh

29
@FKaria make_unique ()는 new직접 호출 할 필요가 없으므로 프로그래머의 사고 방식을 변경하고 메모리 누수를 피할 수 있습니다. "새로 삭제 및 삭제"와 같은 조언은 다음 버전의 Meyers / Alexandrescu / Sutter 's book에 나타날 수 있습니다. :)
cdmh

24

std :: unique_ptr 에는 복사 생성자가 없습니다. 인스턴스를 만든 다음 초기화하는 동안 std :: vector 에게 해당 인스턴스를 복사 하도록 요청하십시오 .

error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::uniqu
e_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_D
eleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> =
 std::unique_ptr<int>]'

이 클래스는 MoveConstructible 및 MoveAssignable의 요구 사항을 충족하지만 CopyConstructible 또는 CopyAssignable의 요구 사항은 충족하지 않습니다.

다음은 새로운 Emplace 통화 와 작동 합니다.

std::vector< std::unique_ptr< int > > vec;
vec.emplace_back( new int( 1984 ) );

자세한 내용 은 표준 라이브러리 컨테이너와 함께 unique_ptr 사용을 참조하십시오 .


5
이 설명을 참조하십시오 - emplace_x()스마트 포인터를 사용할 때는 기능을 사용 하는 것이 안전하지 않습니다.
Qix-MONICA가 MISTREATED

그래서 unique_ptr을 벡터에 저장하는 가장 좋은 방법은 무엇입니까? 테스트 할 때 원시 포인터와 비교할 때 매우 느립니다.
user2189731
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.