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

时间:2016-04-21 19:47:54

标签: c++ c++11 move-semantics

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

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));

我知道在第一种情况下调用副本的原因 - 不会生成移动ctor。但为什么第二个修剪器不能编译?它以为它会再次调用副本。

here是在线编译器的链接

1 个答案:

答案 0 :(得分:1)

差异可归结为移动构造函数与已删除移动构造函数的缺席。这两者并不相同。

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

foo(const foo& );

然后默认选择该候选人。

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

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

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