It has come to my attention that std::forward
is useless in this context:
void consumeObject(std::unique_ptr<Object>&& robj) {
myvector.emplace_back(std::forward<std::unique_ptr<Object>>(robj));
}
Why is that? I thought that by the time an rvalue reference binds to a function parameter (i.e. I can reference it by name) it becomes an lvalue in that scope and in order to be passed forward needs to be casted to an rvalue reference (as in perfect forwarding).
Why is it wrong/useless?
It's not wrong to use std::forward
here (per se), but it is inappropriate and thus misleading (in that sense, you could say that it is actually wrong).
The way you spell "cast something to an rvalue reference to its type" is std::move
. That is the only thing that std::move
does—it's a static_cast<T&&>
where you don't have to spell out the T
.
std::forward
is a different beast, intended for use with perfect forwarding. Perfect forwarding only occurs in templates, where forwarding references are possible. A forwarding reference is a reference which, thanks to a special rule in the language, can deduce to either an lvalue reference or an rvalue reference. There, you need std::forward<T>
to re-instate the appropriate value category (lvalue or rvalue).
Toy example:
void print(int &)
{
std::cout << "Lvalue\n";
}
void print(int &&)
{
std::cout << "Rvalue\n";
}
template <class T>
void perfectForwarder(T &&v)
{
print(std::forward<T>(v));
}
int main()
{
int i;
perfectForwarder(i);
perfectForwarder(std::move(i));
perfectForwarder(42);
}
The output will be:
Lvalue
Rvalue
Rvalue
[Live]
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