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

时间:2021-01-10 16:38:39

I have been reading about the universal references in Scott's last master piece about the c++11 and 14 with that being said despite an argument assigned to either lvalue or an rvalue type reference parameter there is something in between called universal reference which could deduced to either l/rvalue based on the type trait of an argument that passed . I could understand what makes the parameter as an universal reference but the one thing that doesn't clear to me is why adding const to the type parameter const T&& p make the p as rvalue:

我一直在阅读斯科特关于c ++ 11和14的最后一篇关于c ++ 11和14的通用引用,尽管有一个参数分配给左值或右值类型的参考参数,但在它们之间有一些叫做通用引用的东西可以推导出来l / rvalue基于传递的参数的类型特征。我可以理解是什么使得参数成为通用引用但是我不清楚的一个原因是为什么将const添加到类型参数const T && p使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

Does the const do more than this when assigned to the reference parameter.

当分配给引用参数时,const是否会执行更多操作。

1 个解决方案

#1


13  

The official name is not universal reference, but forwarding reference. The Standard states that only rvalue references to cv-unqualified template parameters fall in this category:

官方名称不是通用参考,而是转发参考。标准规定只有对cv-unqualified模板参数的rvalue引用属于此类别:

14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]

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

3 If P is a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction. A forwarding reference is an rvalue reference to a cv-unqualified template parameter. If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction. [ Example:

3如果P是cv限定类型,则类型推导将忽略P类型的*cv限定符。如果P是引用类型,则P引用的类型用于类型推导。转发引用是对cv-unqualified模板参数的rvalue引用。如果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

— end example ]

- 结束例子]

Allowing const T&& to behave as forwarding references, would make it impossible to overload a template function who takes only an rvalue reference as parameter.

允许const T &&表现为转发引用,将使得仅将rvalue引用作为参数的模板函数重载是不可能的。

Update: as @HowardHinnant mentions in the comments, const T&& does have its uses (see also this Q&A).

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

#1


13  

The official name is not universal reference, but forwarding reference. The Standard states that only rvalue references to cv-unqualified template parameters fall in this category:

官方名称不是通用参考,而是转发参考。标准规定只有对cv-unqualified模板参数的rvalue引用属于此类别:

14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]

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

3 If P is a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction. A forwarding reference is an rvalue reference to a cv-unqualified template parameter. If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction. [ Example:

3如果P是cv限定类型,则类型推导将忽略P类型的*cv限定符。如果P是引用类型,则P引用的类型用于类型推导。转发引用是对cv-unqualified模板参数的rvalue引用。如果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

— end example ]

- 结束例子]

Allowing const T&& to behave as forwarding references, would make it impossible to overload a template function who takes only an rvalue reference as parameter.

允许const T &&表现为转发引用,将使得仅将rvalue引用作为参数的模板函数重载是不可能的。

Update: as @HowardHinnant mentions in the comments, const T&& does have its uses (see also this Q&A).

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