If class X is derived from class Y and class Y has any of:
Will a move constructor and move assignment operator be implicitly defaulted for class X providing it declares none of the above?
e.g.
struct Y
{
virtual ~Y() {}
// .... stuff
};
struct X : public Y
{
// ... stuff but no destructor,
// no copy/move assignment operator
// no copy/move constructor
// will X have a default move constructor / assignment operator?
};
I am currently using gcc, but I am mainly interested in what the correct behaviour should be (as opposed to whether or not a particular compiler is standards compliant)..
If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then: No move constructor is automatically generated. No move-assignment operator is automatically generated.
The move assignment operator is different than a move constructor because a move assignment operator is called on an existing object, while a move constructor is called on an object created by the operation. Thereafter, the other object's data is no longer valid.
A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&. This topic builds upon the following C++ class, MemoryBlock , which manages a memory buffer.
std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.
As far as the derived class is concerned, the fact that an attribute or a base class has user-defined or implicit special functions does not matter. All that matter is their presence.
Compliant C++11 compilers should automatically provide the move constructors and assignment operators for the struct and class, if possible (which is clearly defined in the Standard), even though only classes with dynamically allocated buffers will really benefit from it (moving an int
is just copying it).
Therefore, if your class embeds a std::string
or a std::unique_ptr
(for example), then its move constructor will call the embedded string
or unique_ptr
move constructor and it will be efficient... for free.
Simply changing the compilation mode should thus slightly improve performance.
Yes, they are, in §12.8.9:
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
and §12.8.10
The implicitly-declared move constructor for class X will have the form
X::X(X&&)
Similarly, for move assignment operators in 12.8.20:
If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if
Base classes don't come into it directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With