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 &.

Reply via email to