根据C ++ 11 [12.8.9],这个(非平凡的)类X没有隐式声明的移动构造函数,因为X有一个用户声明的复制ctor,一个用户声明的复制赋值操作符,一个用户-declared dtor:
// This counter for objects of class X is only there to make X 'nontrivial':
static int xc = 0;
class X {
public:
X() : p(42) { ++xc; /* ...more nontrivial stuff... */; }
explicit X(const int &t) noexcept : p(t) { ++xc; /* ... */ }
X(const X & other) noexcept : p(other.p) { ++xc; /* ... */ }
//X(X &&) = delete; /* **this is the line in question** */
X& operator=(const X & other) { p = other.p; /* ... */ return *this; }
X& operator=(X && other) { p = other.p; /* ... */ return *this; }
~X() { --xc; /* ... */ }
private:
int p;
};
但是,如果我取消注释删除的移动ctor(即如果我删除移动ctor),我的编译器(GCC 5.2)突然抱怨在编译时移动ctor被删除:
X f(int x)
{
return X(x);
}
我本以为没有删除移动ctor,编译器在从函数f返回X时使用copy ctor,因为这里不允许隐式移动ctor。但那么:为什么明确删除移动ctor会有所作为呢?
答案 0 :(得分:2)
条款"未定义"和"删除"移动构造函数是不同的。即使删除了重载分辨率,也会选择明确定义的移动构造函数。
如果要禁止对象移动并防止重载决策选择已删除的移动构造函数,则应隐式删除移动构造函数:
(自C ++ 14开始)删除的隐式声明的移动构造函数是 被重载决议忽略(否则会阻止 从右值开始复制初始化)
例如,您可以使用已删除的移动构造函数从基类继承该类。