c++ - move 构造函数与复制省略

标签 c++ constructor move-semantics copy-elision

有人可以向我解释一件事。一方面,move constructor旨在通过消除不必要的复制对象来优化内存和处理器的使用,但是从另一面几乎在将要使用move constructor的任何地方进行复制,编译器将使用copy elision,从而禁用move ctor的使用?这是不合理的吗?

最佳答案

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

// 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));
... 还有很多。
从C++ 17开始,唯一必须执行强制删除的情况是从函数调用或构造函数的结果构造值时。在这种情况下,甚至不允许编译器使用move构造函数。例如:
MyObject bar() {
    return MyObject();
}

void example() {
    MyObject x = bar(); // copy elision here
    MyObject y = MyObject(); // also here
}
通常,复制省略的目的是而不是,目的是一起消除移动构造,但在从prvalue初始化变量时避免不必要的构造。

参见cppreference on Copy Elision

关于c++ - move 构造函数与复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63683597/

相关文章:

java - 构造函数和编译

C# 构造函数

c++ - 使用 C++11 复制和 move 时避免代码重复

c++ - move 语义如何在 vector 重定位中起作用?

c++ - 我应该如何正确地将 packaged_task move 到 lambda?

c++ - 什么时候应该在编译前删除目标文件?

c++ - Armadillo 中的有效距离计算

c++ - 在 Redhat 上编译 SOCAT

c++ - 如何使这个带有可变参数的模板特化成为类的 friend ?

Java - 内部类构造函数 - 仅允许外部类