将左值传递给 RValue 的参数

将左值传递给 RValue 的参数

问题描述:

我想知道这怎么可能?

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


int a = 23;
Test(a);

我的问题是函数 Test 需要一个 Rvalue 类型的参数,但它似乎也接受 lvalue 类型的参数.这是为什么 ?那是因为模板的存在吗?因为如果我做这样的事情

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;
}

然后该函数要求参数为 Rvalue 类型.如果有人能解释为什么模板的存在会改变行为,我将不胜感激.

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.

正如您正确想象的那样,关键在于它是一个模板并且参数类型正在推导.当你用一个左值调用 Test 时,参数类型推导规则当参数是一个右值引用时将推导类型 T 为一个左值引用,因此特化变成:

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)

虽然模板采用 rvalue-reference,但如果类型是 lvalue-reference,则参数本身成为 lvalue-reference.

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