2013-01-21 11 views
8

Ich möchte einen beweglichen, aber nicht kopierbaren Typ als Wert in std::map setzen. Hier ist ein einfacher Code, um das Prinzip zu testen.Was ist los mit diesem beweglichen Typ für 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())); 
} 

ich kompilieren dies mit g++ test.cpp --std=c++0x (gcc Version 4.5.1 auf Ubuntu 12.04). Es gibt einen großen hässlichen Fehler, wie unten gezeigt. Was ist das 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

Ich kann keine „Antwort“ hinzufügen, da diese Frage geschlossen ist, aber hier ist es: GCC beschwert, dass es nicht den Kopierkonstruktor von 'std :: pair ' instanziieren kann, weil 'Foo' hat keinen Kopierkonstruktor. GCC benötigt den Kopierkonstruktor von 'std :: pair ' weil ... nun, wegen eines Bibliotheksfehlers: GNU libstdC++ 's 'std :: pair' ist nicht move-enabled! Sie können dies umgehen, indem Sie libC++ oder eine aktualisierte libstdC++ verwenden. Ihr Code ist korrekt wie geschrieben und wird zum Beispiel mit Clang + libC++ kompiliert. – Quuxplusone

+0

Sollte das nicht trivial sein, wenn der Druck lokal kommt? (Fix in der libstdC++, meine ich.) –

Antwort

3

Ich füge einige Details für zukünftige Referenzen: dieser Fehler als Quux verursacht wurde für std::pair in gcc 4.5.1 von a problem in the move constructor hingewiesen.

Ab heute wurde das Problem behoben und Sie sollten entweder Ihre Compiler-Version oder eine Problemumgehung aktualisieren, indem Sie eine andere Version der Standardbibliothek verwenden.

Your code works just fine