Reputation: 4453
Take a look at this code example:
class A {
A(const A&) = delete;
A &operator=(const A&) = delete;
protected:
A() { }
virtual ~A() { } // required for inheritance
A(A&&) = default;
A &operator=(A&&) = default;
};
struct B : public A {
~B() { } // Without the destructor the code compiles
};
int main(void)
{
B b = B();
}
This code fails to compile, wtih g++-9
telling me that (in short)
line 15: error: use of deleted function 'B::B(const B&)'
line 9: note: 'B::B(const B&)' is implicitly deleted because the default definition would be ill-formed:
line 9: error: use of deleted function 'A::A(A&)'
See godbolt for the full error message.
Why does the compiler not use the move constructor/move assignment operator from class A
? If I remove the destructor defined in struct B
the code compiles. What is the reason for this behavior?
Upvotes: 1
Views: 200
Reputation: 180630
When you do
~B() { }
in B
you stop the compiler from generating a move constructor, so all it has is a copy constructor. Since A
's is not acceptable it can't compile.
When you remove it, the compiler can create the move constructor automatically and you're good to go.
Note that this only applies to pre C++17. With C++17's guaranteed copy elision, B b = B();
becomes B b();
(if that would actually compile) so no copy or move happens.
Upvotes: 3