0

Consider this:

void test(int&& param){/*...*/}
int main(){
    int a{444};
    test(a);
}

Certainly It'll not compile because there's no conversion is defined for int to int&&. But the following code:

template<typename T>
void test(T&& param){/*..*/}


int main(){
    int a=826;
    test(a);
    return 0;
}

will compile. But why? What's the reason? There's nothing special about the later except that function test will instantiates for all types T. But we still need to pass rvalue as parameter. So why does it,the later, compile? - without any complaint. Then I tried the following:

template<typename T>
void test(T&& param){/*..*/}

template<typename T>
void test(T param){/*...*/}

int main(){
    int a=826;
    test(a);
    return 0;
}

The compiler complains because function call is ambiguous on whether calling test(T&& param) with T=int& or test(T param) with T=int. Now I am totally baffled on what to deduce. What special does the Template do in here? Why doesn't it conform with the rules on rvalues and lvalues? Thanks in Advance

  • 1
    Possible duplicate of [Rvalue to forwarding references](https://stackoverflow.com/questions/36307479/rvalue-to-forwarding-references) There might be a better dupe – Richard Critten Sep 24 '19 at 12:55
  • 1
    Really good read: https://stackoverflow.com/questions/3582001/advantages-of-using-forward – NathanOliver Sep 24 '19 at 13:01

1 Answers1

0

T&& in this case are sometimes called universal reference or forwarding reference. But the case is that is you're falling in a specific template type deduction rule. The type of param in this case will be int&, then you're not binding a lvalue into a rvalue.

João Paulo
  • 6,300
  • 4
  • 51
  • 80