简体   繁体   中英

Does this code result in a materialized base prvalue, and should it compile?

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM