为什么不调用移动构造函数?

Why isn't the move constructor being called?

我是 C++ 的新手,正在尝试理解右值引用和移动语义。

我写了一个简单的 class、Class,其中包含一个方法 fun,它在其主体中创建 class 的实例,并在 returns 中创建它. class 有一个复制构造函数、一个移动构造函数、一个(复制)赋值运算符和一个(移动)赋值运算符。

以下

Class obj2(obj1.fun()); // ??

obj3 = obj2.fun();      // (move) Assignment operator

既不调用复制构造函数也不调用移动构造函数,而是分别调用(移动)赋值运算符。

obj2 是如何创建的?为什么不

Class obj2(obj1.fun());

调用移动构造函数,

Class obj2(std::move(obj1.fun()));

调用移动构造函数,并且

obj3 = obj2.fun()

调用(移动)赋值运算符(不需要像移动构造函数那样写 std::move(obj2.fun()))?

非常感谢!

Why doesn't Class obj2(obj1.fun()); call the move constructor

因为 Copy Elison。编译器看到fun()return是一个临时对象,那个临时对象只会用来初始化obj2,所以编译器优化了的创建obj2 通过完全消除临时对象并允许直接在 fun() 内部创建 obj2,因此当 fun() 时不需要 copy/move 操作退出。

Class obj2(std::move(obj1.fun())); does call the move constructor

因为你用显式 std::move 强制类型转换,所以编译器无法通过 Copy Elison 优化 obj2 的创建,所以它必须允许 fun() 到 return 一个临时对象,然后将其移动到 obj2 构造函数中。

obj3 = obj2.fun() calls the (move) assignment operator

因为obj3在赋值前已经存在

without needing to write std::move(obj2.fun())

因为fun() return是一个临时对象,它是一个右值,所以在调用移动赋值运算符时不需要显式地将其类型转换为右值。