The std::map class is missing methods for inserting by rvalue reference. As a consequence, move constructible classes (with copying disabled) cannot be used as values. This seems like an oversight since std::vector has this functionality.
The missing methods are: T& operator[](key_type&& x); template <class... Args> pair<iterator, bool> emplace(Args&&... args); template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args); template <class P> pair<iterator, bool> insert(P&& x); template <class P> iterator insert(const_iterator position, P&&); These methods appear to be missing in the trunk as well, so this affects later versions as well. Similar functionality is missing in std::set, std::multimap, and std::multiset. testcase: -------------------------------------------------------------------------------- // Test case for allowing move constructible/assignable classes as values in // std::map. #include <map> // A move constructible/assignable class. struct M { // Default and move constructible. M() {} M(M&&) {} // Move assignable. M& operator=(M&&) { return *this; } // Disable copying. M(const M&) = delete; M& operator=(const M&) = delete; }; int main() { std::map<int, M> m; m.insert(std::map<int, M>::value_type(10, M())); m.insert(m.begin(), std::map<int, M>::value_type(20, M())); m[30] = M(); return 0; } -------------------------------------------------------------------------------- Command line and output: -------------------------------------------------------------------------------- $ g++ -v -o move_test -std=c++0x -save-temps move_map.cc Using built-in specs. Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) COLLECT_GCC_OPTIONS='-v' '-o' 'move_test' '-std=c++0x' '-save-temps' '-shared-libgcc' '-mtune=generic' /usr/lib/gcc/x86_64-linux-gnu/4.4.3/cc1plus -E -quiet -v -D_GNU_SOURCE move_map.cc -D_FORTIFY_SOURCE=2 -mtune=generic -std=c++0x -fpch-preprocess -fstack-protector -o move_map.ii ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../x86_64-linux-gnu/include" ignoring nonexistent directory "/usr/include/x86_64-linux-gnu" #include "..." search starts here: #include <...> search starts here: /usr/include/c++/4.4 /usr/include/c++/4.4/x86_64-linux-gnu /usr/include/c++/4.4/backward /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/4.4.3/include /usr/lib/gcc/x86_64-linux-gnu/4.4.3/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-o' 'move_test' '-std=c++0x' '-save-temps' '-shared-libgcc' '-mtune=generic' /usr/lib/gcc/x86_64-linux-gnu/4.4.3/cc1plus -fpreprocessed move_map.ii -quiet -dumpbase move_map.cc -mtune=generic -auxbase move_map -std=c++0x -version -fstack-protector -o move_map.s GNU C++ (Ubuntu 4.4.3-4ubuntu5) version 4.4.3 (x86_64-linux-gnu) compiled by GNU C version 4.4.3, GMP version 4.3.2, MPFR version 2.4.2-p1. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++ (Ubuntu 4.4.3-4ubuntu5) version 4.4.3 (x86_64-linux-gnu) compiled by GNU C version 4.4.3, GMP version 4.3.2, MPFR version 2.4.2-p1. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 88858f45841827736473e527a4e9ab10 In file included from /usr/include/c++/4.4/bits/stl_algobase.h:67, from /usr/include/c++/4.4/bits/stl_tree.h:63, from /usr/include/c++/4.4/map:61, from move_map.cc:4: move_map.cc: In copy constructor std::pair<const int, M>::pair(const std::pair<const int, M>&): /usr/include/c++/4.4/bits/stl_pair.h:68: instantiated from std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const int, M>&, _Val = std::pair<const int, M>] /usr/include/c++/4.4/ext/new_allocator.h:111: instantiated from void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, _Args&& ...) [with _Args = const std::pair<const int, M>&, _Tp = std::_Rb_tree_node<std::pair<const int, M> >] /usr/include/c++/4.4/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, M>&, _Key = int, _Val = std::pair<const int, M>, _KeyOfValue = std::_Select1st<std::pair<const int, M> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, M> >] /usr/include/c++/4.4/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, M>, _KeyOfValue = std::_Select1st<std::pair<const int, M> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, M> >] /usr/include/c++/4.4/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, M>, _KeyOfValue = std::_Select1st<std::pair<const int, M> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, M> >] /usr/include/c++/4.4/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 = M, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, M> >] move_map.cc:21: instantiated from here move_map.cc:15: error: deleted function M::M(const M&) /usr/include/c++/4.4/bits/stl_pair.h:68: error: used here In file included from /usr/include/c++/4.4/map:61, from move_map.cc:4: /usr/include/c++/4.4/bits/stl_tree.h: In constructor std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const int, M>&, _Val = std::pair<const int, M>]: /usr/include/c++/4.4/bits/stl_tree.h:136: note: synthesized method std::pair<const int, M>::pair(const std::pair<const int, M>&) first required here -------------------------------------------------------------------------------- -- Summary: [C++0x] Cannot use move constructible class as value for std::map Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: hyounes at google dot com GCC build triplet: x86_64-linux-gnu GCC host triplet: x86_64-linux-gnu GCC target triplet: x86_64-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44872