Search code examples
c++rvalue-referencetemplate-argument-deductionconst-referencereference-binding

lvalue and rvalue as function parameters


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
}

Solution

  • 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.