RVO和删除的C++ 14中的移动构造函数

Any*_*ova 6 c++ move-constructor c++14

我最近几天一直在学习(N)RVO.在我阅读c拷贝文章中的cppreference时,对于C++ 14:

...编译器是允许的,但不要求省略复制和移动 - (自C++ 11)类对象的构造,即使复制/移动(自C++ 11)构造函数和析构函数具有可观察的一面效果- .这是一个优化:即使它发生并且没有调用copy-/move-构造函数,它仍然必须存在并且可访问(好像根本没有发生优化),否则程序就会形成错误.

因此,复制移动构造函数必须存在且可访问.但是在下面的代码中:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误: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.

PS我知道在C++ 17标准中,RVO是有义务的.但是NRVO不是,所以我想研究一下这里发生了什么,以便了解何时可以使用NRVO.

lll*_*lll 6

引自cppreference:

已删除的功能

如果,而不是函数体,特殊语法=删除; 使用时,该函数被定义为已删除.

...

如果函数过载,则首先发生重载解析,如果选择了删除的函数,则程序只会格式错误.

如果明确定义要删除的移动构造函数,则不一样.这里由于存在这个删除的移动构造函数,虽然复制构造函数可以匹配,但移动构造函数更好,因此在重载解析期间选择移动构造函数.

如果删除显式delete,则将选择复制构造函数并编译程序.