【发布时间】:2019-07-20 20:46:05
【问题描述】:
在从临时 RVO 初始化堆栈分配的变量时会发生,但在初始化堆分配的变量时不会发生。
#include <iostream>
using namespace std;
class A
{
public:
A() = default;
A(const A &other)
{
cout << "Copy A!" << endl;
}
A(A &&other)
{
cout << "Move A!" << endl;
}
};
A foo()
{
return A();
}
int main()
{
A a1 = foo(); //Constructs A only!
A *a2 = new A(foo()); //Constructs A and moves it
}
输出: 移动A!
在我看来,编译器正在堆栈中创建A,获取指向堆分配内存的指针然后移动A,但是为什么它不先获取指针然后然后通过it to foo,所以A可以直接在堆分配的chunk中构造?
编辑:
使用 g++(i686-posix-dwarf-rev0,由 MinGW-W64 项目构建)5.3.0 编译,使用-O3 -std=c++17
编辑 2: 更新到 MinGW 7.4.0,现在它优化了复制和移动。
【问题讨论】:
-
如果你在 C++17 模式下编译,你应该在这两种情况下都看不到副本和移动。
-
用什么输出?编译器?版本?平台?
-
你确定是MinGW-W64 v5.3.0吗?该版本似乎不存在。
-
@LightnessRacesinOrbit 他们可能意味着 gcc 5.3.0 的 mingw-w64 构建。这是从 2015 年开始的,这将解释不完整的 C++17 支持