我最近几天一直在学习RVO。正如我在复制推荐文章中所读到的,对于C++14:
..。编译器是允许的,但不需要省略类对象的复制和移动(自C++11)构造,即使复制/移动(自C++11)构造函数和析构函数具有明显的副作用。这是一个优化:即使发生了并且没有调用copy-/move-constructor,它仍然必须是,并且必须是可访问的(就好像根本没有进行优化一样),否则程序是错误的。
因此,复制或移动构造函数都必须存在并可访问。但在下面的代码中:
#include <iostream>
class myClass
{
public:
myClass() { std::cout << "Constructor" << std::endl; }
~myClass() { std::cout << "Destructor" << std::endl; }
myClass(myClass const&) { std::cout << "COPY constructor" << std::endl;}
myClass(myClass &&) = delete;
};
myClass foo()
{
return myClass{};
}
int main()
{
myClass m = foo();
return 0;
}我得到了以下错误:test.cpp: In function 'myClass foo()': test.cpp:15:17: error: use of deleted function 'myClass::myClass(myClass&&)' return myClass{};。即使我没有从foo()调用main(),我也会得到这个错误。NRVO也有同样的问题。
因此,移动构造函数总是必需的,不是吗?(虽然副本不是,但我查过了)
我不明白编译器在哪里需要移动构造函数。我唯一的猜测是,它可能是构建临时变量所必需的,但听起来很可疑。有人知道答案吗?
关于编译器:我在g++和VS编译器上尝试过,您可以在线查看它:http://rextester.com/HFT30137。
我知道在C++17标准中,RVO是有义务的。但是NRVO不是,所以我想研究一下这里发生了什么,以了解什么时候我可以使用NRVO。
发布于 2018-02-03 19:28:18
引用自优先选择
删除函数 如果使用特殊语法= delete;而不是函数体,则函数被定义为delete。 ..。 如果函数重载,则首先进行过载解析,如果选择了已删除的函数,则程序只有格式错误。。
如果显式定义要删除的移动构造函数,情况就不一样了。在这里,由于存在这个已删除的移动构造函数,尽管复制构造函数可以匹配,但移动构造函数更好,因此在重载解析过程中选择了移动构造函数。
如果删除显式delete,则将选择复制构造函数并编译程序。
https://stackoverflow.com/questions/48601030
复制相似问题