c++ - 转发引用是否仍然是右值引用?

标签 c++ c++11 rvalue-reference lvalue forwarding-reference

我仍然对为支持移动和转发而发明的规则感到困惑。我仍然不确定的一件事是:

是转发引用只是右值引用(与 引用折叠规则应用)?

如果它是一个右值引用,那么为什么函数:

template<typename T>
void func(T&&);

不仅接受右值,还接受左值?

最佳答案

我不确定这个答案是否会让您满意,但我可以指出标准的相关部分。简而言之,引用 T&& 在“语法上”始终是右值引用,但有时它最终声明的类型是左值引用类型。

当这种情况作为模板参数推导的结果发生时,整个构造称为“转发引用”,作为一种方便的速记。 (这种情况需要引用折叠,但模板参数推导并不是唯一发生引用折叠的情况。)

现在,关于标准措辞。首先我们有 [dcl.ref](例如 p2 , p6 ):

A reference type that is declared using & is called an lvalue reference, and a reference type that is declared using && is called an rvalue reference. [...]

If a typedef-name (9.1.3, 13.1) or a decltype-specifier (9.1.7.2) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR. [Note: This rule is known as reference collapsing. — end note]

最后,模板参数推导的情况在[temp.deduct.call] p3中处理。 :

A forwarding reference is an rvalue reference to a cv-unqualified template parameter [...]

换句话说,转发引用右值引用,但它也接受左值。 (请注意,标准对“转发引用”的定义实际上并不需要推导模板参数,尽管这是您通常希望触发引用折叠行为的主要方式。)

关于c++ - 转发引用是否仍然是右值引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66674195/

相关文章:

c++ - 使用可变参数模板的多键映射

c++ - 在 C++ 中,说一个变量具有右值引用类型有意义吗?

c++ - 将局部变量命名为右值引用有什么意义吗?

c++ - 如何实现具有多个开关的工厂?

c++ - 如何正确传递 ofstream 对象?

c++ - 如何调用在另一个 stackoverflow 中找到的已创建仿函数对象?

c++ - 允许使用右值捕获但不分配给的运算符重载

c++ - 析构函数被调用的次数超过预期

c++ - 推导引用模板参数的类型

C++11 和 Visual Studio - 未解析的外部符号