2011-04-03 123 views
2

如果我定义它接受一个rvalue参考参数的函数:右值参考参数和模板函数

template <typename T> 
void fooT(T &&x) {} 

我可以调用它,使用GCC 4.5,与任一aar,或arr

int a, &ar = a, &&arr = 7; 
fooT(a); fooT(ar); fooT(arr); 

但是,调用类似,非模板功能,

void fooInt(int &&x) {} 

这三个参数中的任何一个都会失败。我正在准备加强我对forward的了解,但是这已经让我失望了。也许它是GCC 4.5;我很惊讶地发现,从A Brief Introduction to Rvalue References第一个例子也给出了编译错误:

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

使这个例子工作的正确方法是明确*使它成为一个右值,其中:A && a_ref2 = std :: move(a)'。 *明确是一件好事,所以你不会意外移动东西。 – GManNickG 2011-04-03 21:22:28

+0

[Scott Meyers的解释](http://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11)。这现在被称为*通用参考* – 2014-06-13 23:11:08

回答

9

扣除的行为模板参数是独特的,是什么原因您的模板版本的作品。在另一个问题的背景下,我已经解释了这种扣减的工作原理here

总结:当所述参数是一个左值,T被推断为T&,和T& &&塌陷到T&。并且在T&的参数下,向它提供左值T是完全有效的。否则,T仍为T,参数为T&&,它接受rvalues参数。

相反,int&&总是int&&(没有模板推导规则强制它到别的东西),并且只能绑定到右值。

6

除了GMAN的正确答案A Brief Introduction to Rvalue References有一个不正确的例子,因为它之前的语言改变其非法的写:

A a; 
A&& a_ref2 = a; // an rvalue reference (DISALLOWED in C++11) 

尽管在语言的这种变化,主要使用(在文章中描述的情况移动和前进)仍然在文章中正确解释。

更新:哦,和同一篇文章最初发布here与(imho)略好的格式。