为什么添加`const`使通用引用成为rvalue

时间:2016-08-07 14:09:07

标签: c++ templates c++11 c++14 forwarding-reference

我一直在阅读Scott关于c ++ 11和14的最后一篇大师文章中的通用引用,尽管有一个参数分配给左值或右值类型参考参数,但它们之间有一些叫做通用引用的东西。可以根据传递的参数的类型特征推导出l / rvalue。我可以理解是什么使得参数成为通用引用但是我不清楚的一个原因是为什么在类型参数const T&& p中添加const使得p为rvalue:

template<typename T>
void f(T&& param); // param is an universal reference

template<typename T>
void f(const T&& param); // param is an rvalue reference

const在分配给参考参数时是否会执行此操作。

1 个答案:

答案 0 :(得分:15)

官方名称不是通用引用,而是forwarding referenceStandard表示仅对 cv-unqualified 模板参数的rvalue引用属于此类别:

  

14.8.2.1从函数调用中减去模板参数[temp.deduct.call]

     

3如果P是cv限定类型,则是P类型的顶级cv限定符   被忽略的类型扣除。如果P是引用类型,则为类型   P所指的用于类型扣除。 转发参考是   对cv非限定模板参数的右值引用。如果P是a   转发引用和参数是左值,类型为“左值”   引用A“代替A代表类型扣除。 [例如:

template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i); // calls f<int&>(int&)
int n2 = f(0); // calls f<int>(int&&)
int n3 = g(i); // error: would call g<int>(const int&&), which
               // would bind an rvalue reference to an lvalue
     

- 结束示例]

允许const T&&表现为转发引用,这样就不可能重载只接受rvalue引用作为参数的模板函数。

更新:正如@HowardHinnant在评论中提到的那样,const T&&确实有其用途(另见this Q&A)。