首页 > 解决方案 > 此代码是否会产生物化的基本纯右值,是否应该编译?

问题描述

以下代码在 gcc 9.1 godbolt中编译,但在 clang 8 godbolt中编译:

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

class B final : public A {
};

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

Clang的错误:

<source>:10:16: error: temporary of type 'A' has protected destructor
    auto b = B{};
               ^
<source>:3:5: note: declared protected here
    ~A() = default;
    ^

哪个是正确的,为什么?

标签: c++language-lawyerc++17destructorcompiler-generated

解决方案


感谢评论中的澄清;由于 C++17B{}是聚合的,即使它是从 派生的A,因此A无权访问dtor. 所以clang拒绝编译是正确的。标准:

没有虚拟、私有或受保护 (C++17 起) 基类

然而,使用()将按照标准所说的那样工作。

基础的dtor可以是公共的或受保护的。

一个共同的准则是基类的析构函数必须是公共的和虚拟的或受保护的和非虚拟的

见标准指南

与 C++11 相比,表达式B()是 a prvalue,并且auto b = B();是一个移动构造,移动可能会被忽略,在 C++17 中,没有移动。prvalue不搬离。这是值初始化B(),完全等同于:

B();

C++17 中的值类别

此代码是否应该无法在 C++17 中编译?


推荐阅读