https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82522
Bug ID: 82522 Summary: std::map::insert(value_type &&) not selected Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jengelh at inai dot de Target Milestone: --- #include <map> struct only_movable { only_movable(){} only_movable(only_movable&&){} only_movable &operator=(only_movable&&){return *this;} }; int main() { std::map<int, only_movable> map; map.insert({0, only_movable()}); } ---- Building this code succeeds with clang++, but fails under g++ 7.2.1/8.0 with: In file included from /opt/wandbox/gcc-head/include/c++/8.0.0/x86_64-pc-linux-gnu/bits/c++allocator.h:33:0, from /opt/wandbox/gcc-head/include/c++/8.0.0/bits/allocator.h:46, from /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:64, from /opt/wandbox/gcc-head/include/c++/8.0.0/map:60, from prog.cc:1: /opt/wandbox/gcc-head/include/c++/8.0.0/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, only_movable>; _Args = {const std::pair<const int, only_movable>&}; _Tp = std::_Rb_tree_node<std::pair<const int, only_movable> >]': /opt/wandbox/gcc-head/include/c++/8.0.0/bits/alloc_traits.h:475:4: required from 'static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const int, only_movable>; _Args = {const std::pair<const int, only_movable>&}; _Tp = std::_Rb_tree_node<std::pair<const int, only_movable> >; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const int, only_movable> > >]' /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:626:32: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::pair<const int, only_movable>&}; _Key = int; _Val = std::pair<const int, only_movable>; _KeyOfValue = std::_Select1st<std::pair<const int, only_movable> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, only_movable> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, only_movable> >*]' /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:643:4: required 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, only_movable>&}; _Key = int; _Val = std::pair<const int, only_movable>; _KeyOfValue = std::_Select1st<std::pair<const int, only_movable> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, only_movable> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, only_movable> >*]' /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:556:62: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Alloc_node::operator()(_Arg&&) const [with _Arg = const std::pair<const int, only_movable>&; _Key = int; _Val = std::pair<const int, only_movable>; _KeyOfValue = std::_Select1st<std::pair<const int, only_movable> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, only_movable> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, only_movable> >*]' /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:1758:29: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, _Arg&&, _NodeGen&) [with _Arg = const std::pair<const int, only_movable>&; _NodeGen = std::_Rb_tree<int, std::pair<const int, only_movable>, std::_Select1st<std::pair<const int, only_movable> >, std::less<int>, std::allocator<std::pair<const int, only_movable> > >::_Alloc_node; _Key = int; _Val = std::pair<const int, only_movable>; _KeyOfValue = std::_Select1st<std::pair<const int, only_movable> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, only_movable> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, only_movable> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]' /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:2101:11: required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = const std::pair<const int, only_movable>&; _Key = int; _Val = std::pair<const int, only_movable>; _KeyOfValue = std::_Select1st<std::pair<const int, only_movable> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, only_movable> >]' /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_map.h:797:41: required from 'std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = int; _Tp = only_movable; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, only_movable> >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const int, only_movable> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, only_movable>]' prog.cc:10:32: required from here /opt/wandbox/gcc-head/include/c++/8.0.0/ext/new_allocator.h:136:4: error: use of deleted function 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = only_movable]' { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_algobase.h:64:0, from /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_tree.h:63, from /opt/wandbox/gcc-head/include/c++/8.0.0/map:60, from prog.cc:1: /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_pair.h:292:17: note: 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = only_movable]' is implicitly deleted because the default definition would be ill-formed: constexpr pair(const pair&) = default; ^~~~ /opt/wandbox/gcc-head/include/c++/8.0.0/bits/stl_pair.h:292:17: error: use of deleted function 'constexpr only_movable::only_movable(const only_movable&)' prog.cc:2:8: note: 'constexpr only_movable::only_movable(const only_movable&)' is implicitly declared as deleted because 'only_movable' declares a move constructor or move assignment operator struct only_movable { ^~~~~~~~~~~~ ---- (I used the online compilers at http://wandbox.org/; equally happens with local one.) So for some reason, g++ decides to not use the insert(value_type &&) and pair(pair &&) variants, and instead opts for const value_type &.