32

我一直在阅读 Scott 关于 c++11 和 14 的最后一篇杰作中的通用引用,尽管有一个参数分配给左值或右值类型引用参数,但在两者之间有一些称为通用引用的东西可以推断为l/rvalue 基于传递的参数的类型特征。我可以理解是什么使参数成为通用引用,但我不清楚的一件事是为什么将 const 添加到类型参数const T&& p会使 p 成为右值:

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做的比这更多。

4

1 回答 1

26

官方名称不是通用引用,而是转发引用。该标准规定,只有对cv 非限定模板参数的右值引用属于此类别:

14.8.2.1 从函数调用中推导出模板参数 [temp.deduct.call]

3 如果 P 是 cv 限定类型,则 P 类型的顶级 cv 限定符将被忽略以进行类型推导。如果 P 是引用类型,则使用 P 所引用的类型进行类型推导。转发引用是对 cv 非限定模板参数的右值引用。如果 P 是转发引用并且参数是左值,则使用类型“对 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&&充当转发引用,将无法重载仅将右值引用作为参数的模板函数。

更新:正如@HowardHinnant 在评论中提到的那样,const T&&确实有它的用途(另见此问答)。

于 2016-08-07T15:27:51.927 回答