I can't do this:
int &&q = 7;
int &&r = q;
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference
If I understand correctly, when initializing an rvalue reference, there's a temporary variable got initialized too. So int &&q = 7;
can be considered as:
int temp = 7;
int &&q = temp;
And when using a reference on the right side, I am actually using the referee. So int &&r = q;
can be considered as:
int &&r = temp; //bind an lvalue to an rvalue reference, cause error, understandable
So above is how I understand the compiler error occurs.
Why adding std::forward
can solve that?
int &&q = 7;
int &&r = std::forward<int>(q);
I know the std::forward
always returns an rvalue reference, how is the reference returned by std::forward
different from int&&q
?
std::forward If arg is an lvalue reference, the function returns arg without modifying its type. This is a helper function to allow perfect forwarding of arguments taken as rvalue references to deduced types, preserving any potential move semantics involved.
When t is a forwarding reference (a function argument that is declared as an rvalue reference to a cv-unqualified function template parameter), this overload forwards the argument to another function with the value category it had when passed to the calling function.
“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable.
You can pass an object to a function that takes an rvalue reference unless the object is marked as const . The following example shows the function f , which is overloaded to take an lvalue reference and an rvalue reference.
how is the reference returned by
std::forward
different fromint&&q
?
Their value categories are different. And note that types and value categories are different things.
q
is a named variable, it's qualified as lvalue, so it can't be bound to rvalue reference.
(emphasis mine)
the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as
std::cin
orstd::endl
. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;
While rvalue reference returned from function is qualified as xvalue, which belongs to rvalue.
a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as
std::move(x)
;
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