右值到左值的转换和 "named-refs-are-lvalues" 规则
Rvalue to lvalue conversion and "named-refs-are-lvalues" rule
有很多与右值相关的问题,但我没有找到这些确切问题的答案。
我无法根据 "named reference is a lvalue reference" 经验法则思考。
这看起来真的很奇怪——我们将引用声明为 rvalue 但由于我们必须以某种方式使用此引用(否则,有什么意义?),我们将其命名并毕竟它被命名为 lvalue!
考虑这段代码:
int&& foo(int&& arg)
{
arg = 10;
return arg; // ERROR, `arg` is an lvalue since it's named!
}
foo(1);
问题是:
- arg 什么时候变成左值?
- 如果函数为空且 b) 和 c) 行不存在,arg 的类型是什么?
- 很多文章(只是引用第一次发现 result)说可能存在隐式左值到右值的转换,但相反的方向是不可能的——为什么?此示例显示
arg
-s 从 int&&
转换为 int&
,然后尝试将 int&
隐式转换为 int&&
,这会导致编译错误——恰恰相反行为!这就是我们需要 std::move
的原因,它基本上是一个显式的 static_cast 右值类型。
arg
变量的类型为 int&&
,没有值类别。
arg
表达式(它是第 3 行和第 4 行的表达式)具有类型 int
和值类别 "lvalue"
左值到右值的转换会更改表达式的值类别,但不会更改其类型。如果您在函数内部编写 arg+1
,类型 int
的左值表达式 arg
将进行此转换以生成类型 int
的纯右值表达式,因为这是内置的+
要求。
int& 和 int&& 之间没有 "lvalue to rvalue" 或反向转换,因为表达式从来没有引用类型。您程序中的错误是无法将右值引用(int&& 类型)绑定 到左值表达式(int
类型)。
有很多与右值相关的问题,但我没有找到这些确切问题的答案。
我无法根据 "named reference is a lvalue reference" 经验法则思考。
这看起来真的很奇怪——我们将引用声明为 rvalue 但由于我们必须以某种方式使用此引用(否则,有什么意义?),我们将其命名并毕竟它被命名为 lvalue!
考虑这段代码:
int&& foo(int&& arg)
{
arg = 10;
return arg; // ERROR, `arg` is an lvalue since it's named!
}
foo(1);
问题是:
- arg 什么时候变成左值?
- 如果函数为空且 b) 和 c) 行不存在,arg 的类型是什么?
- 很多文章(只是引用第一次发现 result)说可能存在隐式左值到右值的转换,但相反的方向是不可能的——为什么?此示例显示
arg
-s 从int&&
转换为int&
,然后尝试将int&
隐式转换为int&&
,这会导致编译错误——恰恰相反行为!这就是我们需要std::move
的原因,它基本上是一个显式的 static_cast 右值类型。
arg
变量的类型为 int&&
,没有值类别。
arg
表达式(它是第 3 行和第 4 行的表达式)具有类型 int
和值类别 "lvalue"
左值到右值的转换会更改表达式的值类别,但不会更改其类型。如果您在函数内部编写 arg+1
,类型 int
的左值表达式 arg
将进行此转换以生成类型 int
的纯右值表达式,因为这是内置的+
要求。
int& 和 int&& 之间没有 "lvalue to rvalue" 或反向转换,因为表达式从来没有引用类型。您程序中的错误是无法将右值引用(int&& 类型)绑定 到左值表达式(int
类型)。