Search code examples
c++templatesrvalue-reference

Passing an Lvalue to a parameter of RValue


I wanted to know how this is possible ?

template<typename T>
void Test(T&& arg)
{
    arg = 14;
}


int a = 23;
Test(a);

My question is that the function Test requires an argument of type Rvalue however it seems to also accept parameter of type lvalue. Why is that ? Is that because of presence of templates ? Because If i do something like this

void AnotherTest(int&& arg)
{
    arg = 14;
}

Then the function requires the parameter to be of type Rvalue. I would appreciate it if someone could explain why presence of Templates changes the behavior.


Solution

  • The key, as you correctly imagined, is that it is a template and that the argument type is being deduced. When you call Test with an lvalue, the rules for argument type deduction when the argument is an rvalue-reference will deduce the type T to be an lvalue-reference, and thus the specialization becomes:

    template <>
    void Test<int&>(int & && arg)
    

    At this point the reference collapsing rules kick in and the type of the argument becomes:

    template <>
    void Test<int&>(int & arg)
    

    While the template takes an rvalue-reference, if the type is an lvalue-reference the argument becomes an lvalue-reference itself.