C++ 右值引用参数和模板函数

C++ 右值引用参数和模板函数,c++,c++11,rvalue-reference,C++,C++11,Rvalue Reference,如果我定义了一个接受右值引用参数的函数: template <typename T> void fooT(T &&x) {} 但是,调用类似的非模板函数 void fooInt(int &&x) {} 这三个论点中的任何一个都将失败。我正准备加强我的前进知识,但这让我偏离了方向。也许是GCC4.5;我惊讶地发现,中的第一个示例也给出了一个编译错误: A a; A&& a_ref2 = a; // an rvalue referen

如果我定义了一个接受右值引用参数的函数:

template <typename T>
void fooT(T &&x) {}
但是,调用类似的非模板函数

void fooInt(int &&x) {}
这三个论点中的任何一个都将失败。我正准备加强我的
前进
知识,但这让我偏离了方向。也许是GCC4.5;我惊讶地发现,中的第一个示例也给出了一个编译错误:

A a;
A&& a_ref2 = a;  // an rvalue reference

模板参数中的推断行为是唯一的,这也是模板版本正常工作的原因。我已经在另一个问题的上下文中解释了这个推论是如何工作的

总结:当参数是左值时,
T
被推断为
T&
,而
T&&&
则折叠为
T&
。使用
T&
处的参数,向其提供左值
T
是完全有效的。否则,
T
保留为
T
,参数为
T&
,它接受右值参数


相反,
int&
始终是
int&
(没有模板演绎规则来强制它到其他东西),并且只能绑定到右值。

除了GMan的正确答案之外,还有一个不正确的例子,因为它是在语言更改之前编写的,而语言更改是非法的:

A a;
A&& a_ref2 = a;  // an rvalue reference (DISALLOWED in C++11)
尽管语言发生了这种变化,文章中描述的主要用例(move and forward)仍然在文章中得到了正确的解释


更新:噢,同一篇文章最初发布时的(imho)格式稍微好一些。

使示例工作的正确方法是显式*将其设为右值,使用:
A&&A\u ref2=std::move(A)
*显式是一件好事,这样你就不会意外地移动东西。。这现在称为通用参考
A a;
A&& a_ref2 = a;  // an rvalue reference (DISALLOWED in C++11)