非生成的特殊成员函数与删除的特殊成员函数

non-generated special member functions vs deleted special member functions

这将编译并调用复制构造函数:

struct foo {
    foo() = default;
    foo(const foo&) { cout << "copy ctor!" << endl; }
    //foo(const foo&&) = delete;
};

int main() {
    foo a;
    foo b(move(a));

这不编译:

struct foo {
    foo() = default;
    foo(const foo&) { cout << "copy ctor!" << endl; }
    foo(const foo&&) = delete;
};

int main() {
    foo a;
    foo b(move(a));

我知道在第一种情况下为什么调用副本 - 没有生成移动构造函数。但是为什么第二个 snipper 不能编译呢?它认为它会再次调用复制ctor。

here 是 link 在线编译器

差异归结为 缺少 移动构造函数与 删除 移动构造函数。这两者并不等同。


在第一种情况下,复制构造函数的存在阻止了隐式移动构造函数的生成。因此,foo(foo&&) 上的重载决策将找到一个可行的候选者:

foo(const foo& );

然后默认选择该候选人。

在第二种情况下,您确实有一个移动构造函数。过载解决方案将找到两个可行的候选者:

foo(const foo& ); // as before
foo(foo&& );      // now this one also exists

移动构造函数是更好的匹配项,因此它被选为最佳可行候选者。但是,由于它被明确定义为已删除,因此选择它的格式不正确。因此编译错误。