2016-01-20 69 views
2

为什么自动& &是不是右参考?auto &&变量的值不是右参考

Widget&& var1 = Widget(); // rvalue reference 
auto&& var2 = var1; //var2 not rvalue reference 
下面

是右值引用例如

void f(Widget&& param); // rvalue reference 
Widget&& var1 = Widget(); // rvalue reference 

为什么VAR2不右值引用,但F和VAR2是右值引用?

+2

我建议你阅读[文章](https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers )转发引用(以前称为通用引用)。 – TartanLlama

+1

添加'auto && var3 = 10'作为右值引用 – bolov

+2

因为指定的右值引用是左值。 – Pixelchemist

回答

0

一旦确定了初始值设定项的类型,编译器就会使用从函数调用(参见模板参数推导#其他上下文获取详细信息)中的模板参数推导规则来确定将替换关键字auto的类型。关键字auto可能伴随有修饰符,例如const&,它们将参与类型推演。

例如,在一个假想的

template template<class U> 
void f(const U& u) 

给出

const auto& i = expr; 

类型的i正是参数u的类型如果函数调用f(expr)编译的。

一般情况下,可以认为如下。

template template<class U> 
    void f(paramtype u) 

因此,auto&&可以根据初始化推断无论是作为一个左值参考或右值参考。

在你的情况下,虚模板看起来像

template template<class U> 
     void f(U&& var2){} 
f(var1) 

这里,var1被命名为正被当作左值右值,所以var2会推导出左值。

请看下面的例子:

auto&& var2 = widget() ; //var2 is rvalue reference here . 
int x=10; 
const int cx=10; 
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int& 
auto&& uref2 = cx; // cx is const int and lvalue, so uref2's type is const int& 
auto&& uref3 = 27; // 27 is int and rvalue, so uref3's type is int&& 
4

auto&&是一个声明的转发参考(具有相同的演绎规则)的等价物。因此,当初始值设定项是左值时,它将被推断为左值引用。但是,var是一个左值(因为它是变量的名称),因此var2是一个左值引用。