Why is this code trying to stuff a pair of - int and a class with a copy constructor not working?

 int main() { std::map<int, A> m; A a; m.insert(std::make_pair(0, a)); return 0; } 

Class A:

 A::A() = default; A::A(A &a) { //smth } 

Error text:

 /home/wcobalt/Files/InstalledPrograms/clion-2018.2.4/bin/cmake/linux/bin/cmake --build /home/wcobalt/Files/test/cmake-build-debug --target test -- -j 2 Scanning dependencies of target test [ 66%] Building CXX object CMakeFiles/test.dir/A.cpp.o [ 66%] Building CXX object CMakeFiles/test.dir/main.cpp.o In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0, from /usr/include/c++/7/bits/char_traits.h:39, from /usr/include/c++/7/ios:40, from /usr/include/c++/7/ostream:38, from /usr/include/c++/7/iostream:39, from /home/wcobalt/Files/test/main.cpp:1: /usr/include/c++/7/bits/stl_pair.h: In instantiation of 'struct std::pair<int, A>': /home/wcobalt/Files/test/main.cpp:11:33: required from here /usr/include/c++/7/bits/stl_pair.h:292:17: error: 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = int; _T2 = A]' declared to take const reference, but implicit declaration would take non-const constexpr pair(const pair&) = default; ^~~~ /usr/include/c++/7/bits/stl_pair.h: In instantiation of 'struct std::pair<const int, A>': /usr/include/c++/7/type_traits:787:65: required by substitution of 'template<class _Tp, class> static std::true_type std::__do_is_destructible_impl::__test(int) [with _Tp = std::pair<const int, A>; <template-parameter-1-2> = <missing>]' /usr/include/c++/7/type_traits:798:35: required from 'struct std::__is_destructible_impl<std::pair<const int, A> >' /usr/include/c++/7/type_traits:809:12: required from 'struct std::__is_destructible_safe<std::pair<const int, A>, false, false>' /usr/include/c++/7/type_traits:824:12: required from 'struct std::is_destructible<std::pair<const int, A> >' /usr/include/c++/7/type_traits:143:12: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] /usr/include/c++/7/type_traits:1070:12: required from 'struct std::__is_direct_constructible_new<std::pair<const int, A>, std::pair<int, A>&&>' /usr/include/c++/7/type_traits:1078:12: required from 'struct std::__is_direct_constructible<std::pair<const int, A>, std::pair<int, A>&&>' /usr/include/c++/7/type_traits:1118:12: required from 'struct std::__is_constructible_impl<std::pair<const int, A>, std::pair<int, A>&&>' /usr/include/c++/7/type_traits:1129:12: required from 'struct std::is_constructible<std::pair<const int, A>, std::pair<int, A>&&>' /usr/include/c++/7/bits/stl_map.h:805:32: required by substitution of 'template<class _Pair, class> std::pair<std::_Rb_tree_iterator<std::pair<const int, A> >, bool> std::map<int, A>::insert<_Pair, <template-parameter-1-2> >(_Pair&&) [with _Pair = std::pair<int, A>; <template-parameter-1-2> = <missing>]' /home/wcobalt/Files/test/main.cpp:11:34: required from here /usr/include/c++/7/bits/stl_pair.h:292:17: error: 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = A]' declared to take const reference, but implicit declaration would take non-const /home/wcobalt/Files/test/main.cpp: In function 'int main()': /home/wcobalt/Files/test/main.cpp:11:34: error: no matching function for call to 'std::map<int, A>::insert(std::pair<int, A>)' m.insert(std::make_pair(0, a)); ^ In file included from /usr/include/c++/7/map:61:0, from /home/wcobalt/Files/test/main.cpp:2: /usr/include/c++/7/bits/stl_map.h:621:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::insert_return_type std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::node_type&&) [with _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::insert_return_type = std::_Node_insert_return<std::_Rb_tree_iterator<std::pair<const int, A> >, std::_Node_handle<int, std::pair<const int, A>, std::allocator<std::_Rb_tree_node<std::pair<const int, A> > > > >; std::map<_Key, _Tp, _Compare, _Alloc>::node_type = std::_Node_handle<int, std::pair<const int, A>, std::allocator<std::_Rb_tree_node<std::pair<const int, A> > > >] insert(node_type&& __nh) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:621:7: note: no known conversion for argument 1 from 'std::pair<int, A>' to 'std::map<int, A>::node_type&& {aka std::_Node_handle<int, std::pair<const int, A>, std::allocator<std::_Rb_tree_node<std::pair<const int, A> > > >&&}' /usr/include/c++/7/bits/stl_map.h:626:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, std::map<_Key, _Tp, _Compare, _Alloc>::node_type&&) [with _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::node_type = std::_Node_handle<int, std::pair<const int, A>, std::allocator<std::_Rb_tree_node<std::pair<const int, A> > > >] insert(const_iterator __hint, node_type&& __nh) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:626:7: note: candidate expects 2 arguments, 1 provided /usr/include/c++/7/bits/stl_map.h:795:7: note: candidate: 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 = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >; 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, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, A>] insert(const value_type& __x) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:795:7: note: no known conversion for argument 1 from 'std::pair<int, A>' to 'const value_type& {aka const std::pair<const int, A>&}' /usr/include/c++/7/bits/stl_map.h:802:7: note: candidate: 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(std::map<_Key, _Tp, _Compare, _Alloc>::value_type&&) [with _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >; 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, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, A>] insert(value_type&& __x) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:802:7: note: no known conversion for argument 1 from 'std::pair<int, A>' to 'std::map<int, A>::value_type&& {aka std::pair<const int, A>&&}' /usr/include/c++/7/bits/stl_map.h:809:2: note: candidate: template<class _Pair, class> 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(_Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >] insert(_Pair&& __x) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:809:2: note: substitution of deduced template arguments resulted in errors seen above /usr/include/c++/7/bits/stl_map.h:823:7: note: candidate: void std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::initializer_list<std::pair<const _Key, _Tp> >) [with _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >] insert(std::initializer_list<value_type> __list) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:823:7: note: no known conversion for argument 1 from 'std::pair<int, A>' to 'std::initializer_list<std::pair<const int, A> >' /usr/include/c++/7/bits/stl_map.h:853:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, A>] insert(const_iterator __position, const value_type& __x) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:853:7: note: candidate expects 2 arguments, 1 provided /usr/include/c++/7/bits/stl_map.h:863:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, std::map<_Key, _Tp, _Compare, _Alloc>::value_type&&) [with _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const int, A>] insert(const_iterator __position, value_type&& __x) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:863:7: note: candidate expects 2 arguments, 1 provided /usr/include/c++/7/bits/stl_map.h:870:2: note: candidate: template<class _Pair, class> std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, _Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >] insert(const_iterator __position, _Pair&& __x) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:870:2: note: template argument deduction/substitution failed: /home/wcobalt/Files/test/main.cpp:11:34: note: candidate expects 2 arguments, 1 provided m.insert(std::make_pair(0, a)); ^ In file included from /usr/include/c++/7/map:61:0, from /home/wcobalt/Files/test/main.cpp:2: /usr/include/c++/7/bits/stl_map.h:886:2: note: candidate: template<class _InputIterator> void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = int; _Tp = A; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, A> >] insert(_InputIterator __first, _InputIterator __last) ^~~~~~ /usr/include/c++/7/bits/stl_map.h:886:2: note: template argument deduction/substitution failed: /home/wcobalt/Files/test/main.cpp:11:34: note: candidate expects 2 arguments, 1 provided m.insert(std::make_pair(0, a)); ^ CMakeFiles/test.dir/build.make:62: recipe for target 'CMakeFiles/test.dir/main.cpp.o' failed make[3]: *** [CMakeFiles/test.dir/main.cpp.o] Error 1 CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/test.dir/all' failed make[2]: *** [CMakeFiles/test.dir/all] Error 2 CMakeFiles/Makefile2:84: recipe for target 'CMakeFiles/test.dir/rule' failed make[1]: *** [CMakeFiles/test.dir/rule] Error 2 Makefile:118: recipe for target 'test' failed make: *** [test] Error 2 

    1 answer 1

    An object passed to such a constructor when called in the pair(const std::pair<_T1, _T2>&) copying constructor pair(const std::pair<_T1, _T2>&) will have a const qualifier. Accordingly, the constructor must be

     A(A const & a) 
    • Really. And there is no difference between const A& and A const& ? - wcobalt 7:34 pm
    • one
      @wcobalt No, although I prefer to always use the usual order ( that is, spiral , which in such an ad degenerates into order from right to left) so as not to suffer from dissonance when there is more than one qualifier in the declaration (for example, char const * const p instead of const char * const p ). - VTT
    • @wcobalt is no difference. "The const qualifier acts on the one on the left, except when it is located first" - the quote is inaccurate, but the meaning is correct. - andy.37