我仍然对为支持移动和转发而发明的规则感到困惑。我仍然不确定的一件事是:
是转发参考,只是右值参考(带有 参考折叠规则适用?)
如果它是右值引用,那么为什么要执行该功能:
template<typename T>
void func(T&&);
不仅接受右值,还接受左值吗?
答案 0 :(得分:1)
在替换T
之前,T &&
是右值引用(很明显)。
在T
被替换之后(并且引用被折叠之后),T &&
仍然是右值引用(如果T
不是引用),或者成为左值引用(如果{ {1}}是左值引用。
答案 1 :(得分:1)
我不确定这个答案是否会让您满意,但是我可以指出标准的相关部分。简而言之,引用T&&
在语法上始终是右值引用,但有时最终声明的类型是左值引用类型。
如果这是模板自变量推导的结果,则整个构造称为“转发参考”,是一种方便的简写。 (这种情况需要引用折叠,但是模板参数推导并不是引用折叠的唯一时间。)
现在,继续使用标准措辞。首先,我们有[dcl.ref](例如p2,p6):
使用
&
声明的引用类型称为左值引用,使用&&
声明的引用类型称为右值引用< / em>。 [...]如果 typedef-name (9.1.3,13.1)或 decltype-specifier (9.1.7.2)表示类型
TR
为引用类型T
,创建类型“对 cvTR
的左值引用”的尝试会创建类型“对T
的左值引用”,而 尝试创建类型“对 cvTR
的右值引用”会创建类型TR
。 [注意:此规则称为参考折叠。 — 尾注]
最后,模板参数推导的情况在[temp.deduct.call] p3中处理:
转发参考是对cv不合格模板参数[...]
的右值参考
换句话说,转发引用是一个右值引用,但它也是一个接受左值的引用。 (请注意,标准的“转发参考”定义实际上不需要推导模板参数,尽管这通常是触发参考折叠行为的主要方式。)