The following code compiles in gcc 9.1 godbolt but not clang 8 godbolt:
class A {
protected:
~A() = default;
};
class B final : public A {
};
int main() {
auto b = B{};
}
Clang's error:
<source>:10:16: error: temporary of type 'A' has protected destructor
auto b = B{};
^
<source>:3:5: note: declared protected here
~A() = default;
^
Which is correct and why?
Thanks for the clarifications in the comments;
Since C++17, B{}
is aggregate even though it is derived from A
, so a temporary A
will be created for the aggregate init by the user which has no access to the dtor
. So clang is correct in rejecting the compile. The standard:
no virtual, private, or protected (since C++17) base classes
However using ()
will work as the standard says.
The dtor
of the base can be public or protected.
A common guideline is that a destructor for a base class must be either public and virtual or protected and nonvirtual
see the guideline of standard
In contrast with C++11, where the expression B()
is a prvalue
, and auto b = B();
is a move-construction and the move will likely get elided, In C++17, there is no move. The prvalue
is not moved from. This is value-initializing B()
and is exactly equivalent to:
B();
Value Categories in C++17
Should this code fail to compile in C++17?
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