2010-02-18 6 views
3

나는 std::unique_ptr<>을 포함하는 클래스가 있으며이 클래스의 인스턴스를 std::map<> 안에 넣고 싶습니다. 나는 C++에 move semantics의 도입을 유도 한 것들 중 하나가 표준 컨테이너 안에 unique_ptrs 같은 것들을 넣을 수있는 가능성이 있다고 생각했다 (벡터의 경우 실제로 작동한다). 하지만 std::map<>은이 아이디어를 좋아하지 않습니다. 이게 왜 그렇게?MoveConstructibles의지도를 만들 수 없습니다.

#include <map> 
#include <memory> 

int main() 
{ 
    std::map<int,std::unique_ptr<int>> map; 

    // error on the line that follows (use of disabled lvalue copy constructor) 
    map.insert(std::make_pair(1,std::unique_ptr<int>(new int(2)))); 

    return 0; 
} 

감사합니다.

mingw32-g++.exe --std=gnu++0x -ID:\CodeEnv\Libraries\Boost -c D:\CodeEnv\CodeMess\Untitled1.cpp -o D:\CodeEnv\CodeMess\Untitled1.o 
mingw32-g++.exe -o D:\CodeEnv\CodeMess\Untitled1.exe D:\CodeEnv\CodeMess\Untitled1.o 
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_algobase.h:66, 
       from c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:62, 
       from c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/map:60, 
       from D:\CodeEnv\CodeMess\Untitled1.cpp:1: 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h: In copy constructor 'std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >::pair(const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&)': 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_pair.h:68: instantiated from 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&, _Val = std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >]' 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/ext/new_allocator.h:111: instantiated from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, _Args&& ...) [with _Args = const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&, _Tp = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >]' 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:394: instantiated from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&, _Key = int, _Val = std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >, _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >]' 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:881: instantiated from 'std::_Rb_tree_iterator<_Val> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(const std::_Rb_tree_node_base*, const std::_Rb_tree_node_base*, const _Val&) [with _Key = int, _Val = std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >, _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >]' 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:1177: instantiated from 'std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = int, _Val = std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >, _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >]' 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_map.h:500: instantiated from 'std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = int, _Tp = std::unique_ptr<int, std::default_delete<int> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int, std::default_delete<int> > > >]' 
D:\CodeEnv\CodeMess\Untitled1.cpp:7: instantiated from here 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/unique_ptr.h:214: 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>]' 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_pair.h:68: error: used here 
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/map:60, 
       from D:\CodeEnv\CodeMess\Untitled1.cpp:1: 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h: In constructor 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&, _Val = std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >]': 
c:\mingw\bin\../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:136: note: synthesized method 'std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >::pair(const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&)' first required here 

그것은처럼 보일 것이다는 std::pair<> 문제이지만, 단독으로 사용되는 경우는 완벽하게 잘 작동 : -

편집, 정확한 오류 메시지가

그냥 더 명확하게하기 위해 있습니다

이 비록
int main() 
{ 
    std::pair<int,std::unique_ptr<int>> pair; 

    pair = std::make_pair(1,std::unique_ptr<int>(new int(2))); // no errors 
    return 0; 
} 

은 분명히 잘못 사용 할 수없는 것을 의미하지 않는다 :

,536,913,632 10
int main() 
{ 
    std::pair<int,std::unique_ptr<int>> pair1,pair2; 

    pair1 = std::make_pair(1,std::unique_ptr<int>(new int(2))); // no errors 
    pair2 = pair1; // BOOM ! Copy from lvalue 
    return 0; 
} 

이는 아마도 std::map<> 내부에서 일어날 것입니다.

단서?

- 편집

오류 메시지를 검토, 정말 TDM-GCC 4.4.1의 std::map<> 구현에 문제가 발생합니다. std::vector<>::push_back(value_type&&)과 같은 이동 의미 기반 삽입 메소드가있는 것은 아닙니다.

지금 무엇을할까요?

+1

우분투에서 g ++ 4.4.1은 분명히 "error : 'unique_ptr'이 'std'의 구성원이 아닙니다." –

+0

--std = C++ 0x (또는 --std = gnu)로 소스를 컴파일해야합니다. ++ 0x, something 이와 같이) unique_ptr을 ''에서 사용할 수 있습니다. 아마도 그 메시지를 보는 이유 일 것입니다. 여기서 unique_ptr은 잘 사용됩니다. std :: map에이 엉망이 있습니다. –

+0

'map'이 복사 할 수없는 타입을 처리 할 수 ​​없다면이 단일 문제 만 해결하면 도움이되지 않습니다. 조만간 다른 문제가 발생할 것입니다. –

답변

2

동일한 문제가 발생했습니다. 나는 비트/stl_map.h와 bits/stl_tree.h를 패치함으로써 많은 노력을 들이지 않고 필요한 기능을 추가 할 수 있었다. 특정 예제가 작동하도록하려면 기본적으로 insert (value_type & &) 메소드를 맵 클래스에 추가해야합니다. 이것은 본질적으로 insert (const value_type &)와 동일하지만, 적절한 경우 std :: move()를 사용합니다. 올바른 지원 방법을 추가해야하지만 컴파일 오류를 사용하여 필요한 것을 알려줄 수 있습니다.

이 문제는 GCC 팀 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44436)에보고되었으며 다른 사람이 작업 중이므로 조만간 연관성이있는 컨테이너와 순서가없는 컨테이너로 이동 가능한 구문을 지원할 예정입니다.

1

어떤 컴파일러를 사용하고 있습니까? 그것은 VS10 베타 괜찮 컴파일 2.


편집 : 문제의 컴파일러는 GCC

이의 STL 구현에서 버그가 수 있도록 표시 GCC는 오픈 소스이기 때문에 당신이 패치 고정을 제출할 수있다 이 문제.
다행히 수정 프로그램은 컴파일러 코드가 아닌 STL 코드에 있으므로 너무 어려워서는 안됩니다.

그동안 로컬 pair/map 헤더 파일에 수정 프로그램을 입력 할 수 있습니다.

+0

GCC 4.4.1을 사용하고 있습니다. –

+0

그건 그렇고, 실제로는 Windows 용 GCC 4.4.1 포트입니다 (TDM-GCC : http://www.tdragon.net/recentgcc/). –

+0

하하. 나는 지금 당장 그것을 해왔다. 비참하게 실패했다 :] 실제로 나는 패치하기에 너무 많은 것들이 있다는 것을 느꼈다. 그래서 나는 포기했다. 나는 GCC에서 구현되지 않았고 VC++에서 구현 되었다면 이렇게 될 수있는 어두운 이유가있을 수있다. 그럼에도 불구하고 TDM-GCC 개발자에게 버그 보고서를 제출했다. : //sourceforge.net/tracker/? func = detail & aid = 2954089 & group_id = 200665 & atid = 974439). 감사. –

관련 문제