Reputation: 318
The following code is similar to this answer Why can't I make a vector of references?
class A
{
public:
A(int x) : _x(x)
{
std::cout << "A : ctor\n";
}
void func()
{
std::cout << "I am func \n";
}
int getval()
{
return _x;
}
private:
int _x;
};
int main()
{
A a1(2);
A a2(3);
std::vector<std::reference_wrapper<A>> vec;
vec.push_back(std::ref(a1));
vec.push_back(std::ref(a2));
for(auto v : vec)
{
std::remove_reference<A&>::type(v).func();
std::cout << std::remove_reference<A&>::type(v).getval() << "\n";
}
}
I need to be able to resize vec (e.g. vec.resize(100)) and have something like
vec[n] = std::ref(b);
but I'll get this error which I don't quite understand:
/usr/include/c++/7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::reference_wrapper<A>; _Args = {}]’:
/usr/include/c++/7/bits/stl_uninitialized.h:527:18: required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = std::reference_wrapper<A>*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/7/bits/stl_uninitialized.h:583:20: required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = std::reference_wrapper<A>*; _Size = long unsigned int]’
/usr/include/c++/7/bits/stl_uninitialized.h:645:44: required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = std::reference_wrapper<A>*; _Size = long unsigned int; _Tp = std::reference_wrapper<A>]’
/usr/include/c++/7/bits/vector.tcc:563:35: required from ‘void std::vector<_Tp, _Alloc>::_M_default_append(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::reference_wrapper<A>; _Alloc = std::allocator<std::reference_wrapper<A> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/7/bits/stl_vector.h:692:21: required from ‘void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = std::reference_wrapper<A>; _Alloc = std::allocator<std::reference_wrapper<A> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
<span class="error_line" onclick="ide.gotoLine('main.cpp',47)">main.cpp:47:19</span>: required from here
/usr/include/c++/7/bits/stl_construct.h:75:7: error: no matching function for call to ‘std::reference_wrapper::reference_wrapper()’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/bits/shared_ptr_base.h:56:0,
from /usr/include/c++/7/bits/shared_ptr.h:52,
from /usr/include/c++/7/memory:81,
from main.cpp:5:
/usr/include/c++/7/bits/refwrap.h:340:7: note: candidate: constexpr std::reference_wrapper<_Tp>::reference_wrapper(const std::reference_wrapper<_Tp>&) [with _Tp = A]
reference_wrapper(const reference_wrapper&) = default;
^~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/refwrap.h:340:7: note: candidate expects 1 argument, 0 provided
/usr/include/c++/7/bits/refwrap.h:334:7: note: candidate: std::reference_wrapper<_Tp>::reference_wrapper(_Tp&) [with _Tp = A]
reference_wrapper(_Tp& __indata) noexcept
^~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/refwrap.h:334:7: note: candidate expects 1 argument, 0 provided
Is there a way to have this capability for the given example?
Thanks
Upvotes: 2
Views: 360
Reputation: 19113
error: no matching function for call to ‘std::reference_wrapper::reference_wrapper()’
That says wrapper's default constructor was not found. It does not have one because references must always be initialized.
std::vector<T>::resize
uses this default constructor to initialize new elements. Think about it, what should this print?
std::vector<std::reference_wrapper<A>> vec;
vec.resize(100); # There now must be 100 valid elements.
std::cout << vec[50].get().getval();
If you want default semantics, use pointers.
If you call resize as an optimization, just use reserve
+push_back
.
Upvotes: 3