首页 > 解决方案 > 为什么删除移动构造函数会导致编译错误?

问题描述

以下代码可以正常工作:

#include <iostream>
using namespace std;
struct oops
{
        ~oops()
        {
                cout << " oops! " << endl;
        }
};

struct sample
{
        oops* x = nullptr;
        sample(oops* p) : x(p)
        {
                cout << "sample: " << p << endl;
        }
        ~sample()
        {
                delete x;
                cout << "destroy sample " << endl;
        }
        sample(const sample&)
        {
                cout << "copy sample " << endl;
        }
        sample(sample&&)
        {
                cout << "move sample " << endl;
        }
};

int main()
{
        sample s = new oops;
        return 0;
}

结果:

sample: 0x1470c20
 oops!
destroy sample

它清楚地表明,既没有调用移动构造函数,也没有调用复制构造函数。当这些构造函数被删除时,

sample(const sample&) = delete;
sample(sample&&) = delete;

gcc 给出编译错误:

bpp.cpp: In function ‘int main()’:
bpp.cpp:29:17: error: use of deleted function ‘sample::sample(sample&&)’
  sample s = new oops;
                 ^
bpp.cpp:24:2: note: declared here
  sample(sample&&) = delete;
  ^
bpp.cpp:14:2: note:   after user-defined conversion: sample::sample(oops*)
  sample(oops* p) : x(p)
  ^

这有关系-fno-elide-constructors吗?如何在不定义这些构造函数或使用显式构造函数的情况下编译它?

编辑:我的 GCC 版本是 5.4.0。命令是:

g++ bpp.cpp -std=c++17

标签: c++gcc

解决方案


sample s = new oops;

这是复制初始化的一种形式。要让编译器在 C++17 之前解析它,必须存在复制或移动构造函数。但是,由于优化,编译器可以自由地省略其调用(使用 GCC 和-fno-elide-constructors,调用移动构造函数)。

从 C++17 开始,这些构造函数都不需要:https ://wandbox.org/permlink/3V8glnpqF5QxljJl 。


如何在不定义这些构造函数或使用显式构造函数的情况下编译它?

很简单,避免复制初始化,而是使用直接初始化

sample s { new oops };

或者,使用 C++17。


推荐阅读