2013-01-21 2 views
8

std::map에 값으로 이동 가능하지만 복사 할 수없는 유형을 넣으려고합니다. 원칙을 테스트하는 간단한 코드가 있습니다.std :: map에 대한이 이동식 유형의 문제점은 무엇입니까?

#include <map> 

struct Foo 
{ 
    Foo(); 

    Foo (const Foo &) = delete; 
    Foo & operator = (const Foo &) = delete; 

    Foo (Foo &&) {} 
    Foo & operator = (Foo &&) {return *this;} 
}; 

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

    m .insert (std :: make_pair (123, Foo())); 
} 

나는 g++ test.cpp --std=c++0x (GCC 우분투 12.04에 버전 4.5.1)로이 컴파일. 아래에 표시된 것처럼 큰 추악한 오류가 있습니다. 문제가 무엇입니까?

In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_algobase.h:66:0, 
       from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:62, 
       from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/map:60, 
       from test.cpp:1: test.cpp: In copy constructor ‘std::pair<const int, Foo>::pair(const std::pair<const int, Foo>&)’: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_pair.h:72:5: instantiated from ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Val = std::pair<const int, Foo>]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/ext/new_allocator.h:111:4: instantiated from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, 
_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Tp = std::_Rb_tree_node<std::pair<const int, Foo> >, _Tp* = std::_Rb_tree_node<std::pair<const int, Foo> >*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:394:8: 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, Foo>&}, _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, std::_Rb_tree_node<_Val>* = std::_Rb_tree_node<std::pair<const int, Foo> >*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:899:42: instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, 
_Alloc>::iterator 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, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, Foo> >, const std::_Rb_tree_node_base* = const std::_Rb_tree_node_base*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:1191:65: instantiated from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, 
_Alloc>::_M_insert_unique(const _Val&) [with _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_map.h:501:41: instantiated from ‘std::pair<typename std::map<_Key, _Tp, _Compare, 
_Alloc>::_Rep_type::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::map<_Key, _Tp, _Compare, _Alloc>::value_type&) [with _Key = int, _Tp = Foo, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, typename std::map<_Key, _Tp, _Compare, _Alloc>::_Rep_type::iterator = std::_Rb_tree_iterator<std::pair<const int, Foo> >, std::map<_Key, 
_Tp, _Compare, _Alloc>::value_type = std::pair<const int, Foo>]’ test.cpp:20:43: instantiated from here test.cpp:7:2: error: deleted function ‘Foo::Foo(const Foo&)’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_pair.h:72:5: error: used here In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/map:60:0, 
       from test.cpp:1: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h: In constructor ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Val = std::pair<const int, Foo>]’: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:136:49: note: synthesized method ‘std::pair<const int, Foo>::pair(const std::pair<const int, Foo>&)’ first required here 
+3

나는 "답"을 추가 할 수는 없지만 여기있다 : GCC가 있기 때문에, 그것은 표준 : : 쌍 ''의 복사 생성자를 인스턴스화 할 수없는 불평 'Foo'는 복사 생성자가 없습니다. GCC는'std :: pair '의 복사 생성자를 필요로합니다 ... 왜냐하면 ... 라이브러리 버그로 인해 : GNU libstdC++의'std :: pair'는 이동 가능하지 않습니다! libC++ 또는 업데이트 된 libstdC++를 사용하여이 문제를 해결할 수 있습니다. 코드는 작성된대로 정확하며 Clang + libC++로 컴파일됩니다. – Quuxplusone

+0

푸시가 로컬로 밀리면 문제가 해결되지 않아야합니까? (libstdC++에서 수정되었습니다.) –

답변

3

나는 미래의 참조에 대한 몇 가지 세부 사항을 추가 해요 : Quux 등이 버그가 std::pair에 대한 a problem in the move constructor에 의해 GCC 4.5.1에서 발생 된 지적했다.

현재까지이 문제는 수정되었으며 다른 버전의 표준 라이브러리를 사용하여 컴파일러 버전이나 해결 방법을 업그레이드해야합니다. 이 질문에 폐쇄되기 때문에

Your code works just fine

관련 문제