I thought maps and reference_wrappers would go easy but I tripped over something weird:
#include <map>
#include <functional>
int main(void) {
std::map<int, std::reference_wrapper<const int>> mb;
const int a = 5;
mb[0] = std::cref(a);
}
This piece of code gives me the following compiler error:
In file included from c:/MinGW/x86_64-w64-mingw32/include/c++/bits/stl_map.h:63:0,
from c:/MinGW/x86_64-w64-mingw32/include/c++/map:61,
from ../test/main.cpp:9:
c:/MinGW/x86_64-w64-mingw32/include/c++/tuple: In instantiation of 'std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {int&&}; long long unsigned int ..._Indexes1 = {0ull}; _Args2 = {}; long long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = std::reference_wrapper<const int>]':
c:/MinGW/x86_64-w64-mingw32/include/c++/tuple:1083:63: required from 'std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {int&&}; _Args2 = {}; _T1 = const int; _T2 = std::reference_wrapper<const int>]'
c:/MinGW/x86_64-w64-mingw32/include/c++/ext/new_allocator.h:120:4: required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, std::reference_wrapper<const int> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, std::reference_wrapper<const int> > >]'
c:/MinGW/x86_64-w64-mingw32/include/c++/bits/alloc_traits.h:253:4: required from 'static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::pair<const int, std::reference_wrapper<const int> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const int, std::reference_wrapper<const int> > > >; std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> = void]'
c:/MinGW/x86_64-w64-mingw32/include/c++/bits/alloc_traits.h:399:57: required from 'static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::pair<const int, std::reference_wrapper<const int> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const int, std::reference_wrapper<const int> > > >; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]'
c:/MinGW/x86_64-w64-mingw32/include/c++/bits/stl_tree.h:423:42: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, std::reference_wrapper<const int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::reference_wrapper<const int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::reference_wrapper<const int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::reference_wrapper<const int> > >*]'
c:/MinGW/x86_64-w64-mingw32/include/c++/bits/stl_tree.h:1789:64: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, std::reference_wrapper<const int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::reference_wrapper<const int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::reference_wrapper<const int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, std::reference_wrapper<const int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, std::reference_wrapper<const int> > >]'
c:/MinGW/x86_64-w64-mingw32/include/c++/bits/stl_map.h:519:8: required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = int; _Tp = std::reference_wrapper<const int>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::reference_wrapper<const int> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::reference_wrapper<const int>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]'
../test/main.cpp:20:6: required from here
c:/MinGW/x86_64-w64-mingw32/include/c++/tuple:1094:70: error: no matching function for call to 'std::reference_wrapper<const int>::reference_wrapper()'
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
c:/MinGW/x86_64-w64-mingw32/include/c++/tuple:1094:70: note: candidates are:
In file included from ../test/main.cpp:10:0:
c:/MinGW/x86_64-w64-mingw32/include/c++/functional:413:7: note: std::reference_wrapper<_Tp>::reference_wrapper(const std::reference_wrapper<_Tp>&) [with _Tp = const int]
reference_wrapper(const reference_wrapper<_Tp>& __inref) noexcept
^
c:/MinGW/x86_64-w64-mingw32/include/c++/functional:413:7: note: candidate expects 1 argument, 0 provided
c:/MinGW/x86_64-w64-mingw32/include/c++/functional:407:7: note: std::reference_wrapper<_Tp>::reference_wrapper(_Tp&) [with _Tp = const int]
reference_wrapper(_Tp& __indata) noexcept
^
c:/MinGW/x86_64-w64-mingw32/include/c++/functional:407:7: note: candidate expects 1 argument, 0 provided
Am I doing something really, really stupid here that I should be aware of? Why isn't this little piece of code working straight forward?
The operator[]
of an std::map<K, T>
requires that T
be default-constructible.
Use this instead:
m.emplace(0, std::cref(a));
In C++17, you can also use one of these:
m.try_emplace(0, std::cref(a));
m.insert_or_assign(0, std::cref(a));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With