I have a local std::vector<std::reference_wrapper<T> >
and now I want to return a real copy of its elements (i.e std::vector<T>
). Is there a better way than a loop?
Example:
std::vector<T> foobar() {
std::vector<std::reference_wrapper<T> > refsToLocals;
/*
do smth with refsToLocals
*/
std::vector<T> copyOfLocals;
for (auto local : refsToLocals)
copyOfLocals.insert_back(local.get());
return copyOfLocals;
}
It's a flaw in the C++ language. You can't take the address of a reference, since attempting to do so would result in the address of the object being referred to, and thus you can never get a pointer to a reference.
(since C++11) std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is frequently used as a mechanism to store references inside standard containers (like std::vector) which cannot normally hold references.
A reference_wrapper can be used to store references in standard containers, and to pass objects by reference to std::bind . The type Ty must be an object type or a function type, or a static assert fails at compile time. The helper functions std::ref and std::cref can be used to create reference_wrapper objects.
It seems, the obvious approach is to just construct a std::vector<T>
from a sequence from the std::vector<std::reference_wrapper<T>>
:
std::vector<T> foobar() {
std::vector<std::reference_wrapper<T> > refsToLocals;
/* do smth with refsToLocals */
return std::vector<T>(refsToLocals.begin(), refsToLocals.end());
}
You could use std::copy
this way:
std::copy(
refsToLocals.begin(),
refsToLocals.end(),
std::back_inserter(copyOfLocals));
Be sure to use call copyOfLocals.reserve(refsToLocals.size())
. It will minimize copies and heap-allocations.
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