Reputation: 73
According to C++11 [12.8.9], this (nontrivial) class X does not have an implicitly declared move constructor, because X has a user-declared copy ctor, a user-declared copy assignment operator, a user-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;
};
However, if I uncomment the deleted move ctor (i.e. if I delete the move ctor), my compiler (GCC 5.2) suddenly complains about the move ctor being deleted when compiling this:
X f(int x)
{
return X(x);
}
I would have supposed that with out deleted move ctor the compiler uses the copy ctor when returning an X from function f since an implicit move ctor is not allowed here. But then: why does it make a difference to explicitly delete the move ctor?
Upvotes: 2
Views: 102
Reputation: 2629
The terms "not defined" and "deleted" move constructor are different. Explicitly defined move constructor is chosen by overload resolution even if it is deleted.
If you want to forbid object moving and prevent overload resolution from selecting deleted move constructor, the move constructor should be implicitly deleted:
(since C++14)The deleted implicitly-declared move constructor is ignored by overload resolution (otherwise it would prevent copy-initialization from rvalue)
For example, you can inherit the class from base class with deleted move constructor.
Upvotes: 2