移动构造函数与复制省略

Der*_*k81 1 c++ constructor move-semantics copy-elision

有人可以向我解释一件事吗?从一方面来看,它的move constructor设计目的是通过消除不必要的复制对象来优化内存和处理器的使用,但从另一面来看,几乎所有地方move constructor都会使用编译器使用复制省略move ctor,禁用?的使用。这不是不合理吗?

Jan*_*tke 6

在很多情况下,移动构造函数仍然会被调用并且复制省略不会被使用:

// inserting existing objects into a container
MyObject myobject;
std::vector<MyObject> myvector;
myvector.push_back(std::move(myobject));

// inserting temporary objects into a container
myvector.push_back(MyObject());

// swapping
MyObject other;
std::swap(myobject, other);

// calling functions with existing objects
void foo(MyObject x);

foo(std::move(myobject));
Run Code Online (Sandbox Code Playgroud)

... 还有很多。

强制复制省略的唯一实例(自 C++17 起)是从函数调用或构造函数的结果构造值时。在这种情况下,编译器甚至不允许使用移动构造函数。例如:

MyObject bar() {
    return MyObject();
}

void example() {
    MyObject x = bar(); // copy elision here
    MyObject y = MyObject(); // also here
}
Run Code Online (Sandbox Code Playgroud)

一般来说,复制省略的目的不是完全消除移动构造,而是在从纯右值初始化变量时避免不必要的构造。


请参阅cppreference 有关复制消除的内容