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, ifT
isconst int&
, then what isT&&
i.e.const int& &&
? Reference collapsing rules say that it isconst int&
.So, when
T
inT&&
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.