为什么在我的代码中调用复制构造函数而不是移动构造函数?

use*_*549 2 c++ rvalue-reference c++11

我试图了解移动构造函数和右值引用。所以我在https://www.onlinegdb.com/online_c++_compiler上尝试了此代码。但是结果使我感到困惑。

#include <iostream>
#include <type_traits>


class A {
public:
  A() { std::cout << "Constructed" << std::endl; }
  A(const A& )= delete;
  A(A&&) { std::cout << "Move Constructed" << std::endl; }
};

int
main ()
{
  A&& a = A();
  A b = a; // error: use of deleted function ‘A::A(const A&)’
  //A b = static_cast<decltype(a)>(a); // This works, WTF?
  std::cout << std::is_rvalue_reference<decltype(a)>::value << std::endl; // pretty sure a is rvalue reference.

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

son*_*yao 5

您对类型值类别感到困惑。

(强调我的)

每个C ++表达式(具有其操作数,文字,变量名等的运算符)都具有两个独立的属性:typevalue category

作为一个命名变量,a是一个左值。

以下表达式是左值表达式

  • 变量的名称,...
  • ...

然后为A b = a;复制构造函数选择。如您所试,static_cast<decltype(a)>(a);将其转换为xvalue(即rvalue);您也可以使用std::move

A b = std::move(a);
Run Code Online (Sandbox Code Playgroud)

以下表达式是xvalue表达式

  • 函数调用或重载的运算符表达式,其返回类型是对对象的右值引用,例如std::move(x)
  • ...