简体   繁体   English

此代码是否会产生物化的基本prvalue,并应进行编译?

[英]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 : 以下代码在gcc 9.1 godbolt中编译,但在clang 8 godbolt中编译

class A {
protected:
    ~A() = default;
};

class B final : public A {
};

int main() {
    auto b = B{};
}

Clang's error: lang的错误:

<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 . 由于C ++ 17,即使B{}是从A派生A ,它也是聚合A ,因此将由无法访问dtor的用户为聚合init创建一个临时A So clang is correct in rejecting the compile. 因此clang在拒绝编译时是正确的。 The standard: 标准:

no virtual, private, or protected (since C++17) base classes 没有虚拟,私有或受保护的(自C ++ 17起)基类

However using () will work as the standard says. 但是,使用()将按标准要求工作。

The dtor of the base can be public or protected. 基地的dtor者可以是公开的或受保护的。

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(); 与C ++ 11相反,其中表达式B()prvalue ,而auto b = B(); is a move-construction and the move will likely get elided, In C++17, there is no move. 是一个动作构造,并且该动作可能会被忽略。在C ++ 17中,没有动作。 The prvalue is not moved from. prvalue不会移出。 This is value-initializing B() and is exactly equivalent to: 这是对B()值初始化,并且完全等效于:

B();

Value Categories in C++17 C ++ 17中的值类别

Should this code fail to compile in C++17? 此代码是否应该无法在C ++ 17中编译?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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