I'm trying to understand Lvalue and Rvalue in C ++.
So I'm using them as parameters passed to the functions. In this first case I have two functions, the first has a reference to an const int, in this case thanks to "const" (see link) I can pass to the first function both a Lvalue and a Rvalue and I will have no problems. At the second function instead I am obliged to pass a Rvlaue otherwise I get the error described.
void f1(const int& n){cout<<"[Lvalue]"<<endl;}
void f2(int&& n){cout<<"[Rvalue]"<<endl;}
int main()
{
const int n = 10;
f1(n);
f2(n); //error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘const int’
}
ok!
Why if the second function becomes a function template, as in the example below I can also pass a Lvalue.
void f1(const int& n){cout<<"[Lvalue]"<<endl;}
template<class T>
void f2(T&& n){cout<<"[Rvalue]"<<endl;}
int main()
{
const int n = 10;
f1(n);
f2(n); //ok
}
What is important is that T
was deduced to be a reference. So, if T
is const int&
, then what is T&&
i.e. const int& &&
? Reference collapsing rules say that it is const int&
.
So, when T
in T&&
is deduced, that &&
doesn't denote rvalue reference, but a reference whose type is deduced, and may be either rvalue or lvalue reference depending on the result of the deduction. It is said to be a forwarding reference.