C++ 11:为什么rvalue引用参数隐式转换为lvalue

Cod*_*eve 1 c++ rvalue-reference c++11

以下是我的问题的简单代码,

void overloaded (int&& x) {
  cout << "[rvalue]";
}

template <class T>
void fn (T&& x) {
  overloaded(x);
}

int main() {
    fn(0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我遇到了编译错误

无法将' int'左值' 绑定到' int&&'

  overloaded(x);
Run Code Online (Sandbox Code Playgroud)

我在这里很困惑,x作为右值引用传入fn().但为什么抱怨的overload()电话是一个左值?fn()x

Ker*_* SB 6

你不是" x作为右值参考传递",因为这个陈述并不真正有意义.

以下是关于C++中类型和表达式分类的一系列事实:

  • 有对象类型和引用类型.(还有其他一些类型.)

  • 变量可以是对象或引用.

  • 表达式有类型,这些类型(几乎)总是对象类型,从不引用.(这就是为什么你的"传递某些东西作为参考"的陈述没有意义;你传递参数和参数总是表达式.)表达式可以是左值,右值或右值.

  • 左值引用绑定到左值.Rvalue引用绑定到rvalues.(右值是prvalue或xvalue.)

  • 命名变量或参数的id-expression是左值.(如果你愿意的话,这是一个"有名字的东西"或"一个地方".)

因此在表达式中overloaded(x),子表达式x是一个左值,它不会绑定到需要rvalue的函数(由于它的rvalue引用参数).

"左值引用"和"右值引用"中的"l"和"r"是指引用可以绑定的值的类别,而不是指定此引用类型的变量的id-expression的类别.

您可以通过将左值转换为x值来将左值转换为右值.这可以方便地封装到类型演绎的强制助手中std::move.