右值到左值的转换和 "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);

问题是:

  1. arg 什么时候变成左值?
  2. 如果函数为空且 b) 和 c) 行不存在,arg 的类型是什么?
  3. 很多文章(只是引用第一次发现 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 类型)。