2013-01-21 5 views
8

chcę umieścić ruchomy ale nie copyable typ jako wartość w std::map. Oto prosty kod do sprawdzenia zasady.Co jest nie tak z tym ruchomym typu dla 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())); 
} 

skompilować to z g++ test.cpp --std=c++0x (wersja 4.5.1 na Ubuntu 12.04 GCC). Istnieje wielki brzydki błąd, jak pokazano poniżej. Jaki jest problem?

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

nie mogę dodać „odpowiedź”, ponieważ kwestia ta jest zamknięta, ale tutaj jest: GCC narzeka, że ​​nie można utworzyć wystąpienia konstruktora kopii 'std :: pair ', ponieważ 'Foo' nie ma konstruktora kopiowania. GCC wymaga konstruktora kopii 'std :: pair ' bo ... dobrze, z powodu błędu biblioteki GNU libstdC++ 's 'std :: pair' nie poruszać obsługującej! Możesz obejść to, używając libC++ lub zaktualizowanego libstdC++. Twój kod jest poprawny, jak napisane, i skompilować z Clang + libC++, na przykład. – Quuxplusone

+0

Nie powinno to być banalne naprawić, jeśli przyjdzie co do czego lokalnie? (Naprawię w libstdC++, mam na myśli.) –

Odpowiedz

3

Dodaję kilka szczegółów dla przyszłych odniesień: ten błąd jako quux wskazał została spowodowana w gcc 4.5.1 przez a problem in the move constructor dla std::pair.

dzień dzisiejszy problem został naprawiony i należy albo uaktualnić swoją wersję kompilatora lub obejścia przy użyciu innej wersji standardowej biblioteki.

Your code works just fine

Powiązane problemy