[Bug libstdc++/44872] New: [C++0x] Cannot use move constructible class as value for std::map

hyounes at google dot com gcc-bugzilla@gcc.gnu.org
Thu Jul 8 13:48:00 GMT 2010


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



More information about the Gcc-bugs mailing list