[英]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.