Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 526
Rajeshwar Avatar asked Sep 30 '22 19:09

Rajeshwar


1 Answers

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.

like image 187
David Rodríguez - dribeas Avatar answered Oct 04 '22 19:10

David Rodríguez - dribeas