c++ - 这段代码是否会产生物化的基纯右值,它应该编译吗?

标签 c++ language-lawyer c++17 destructor compiler-generated

以下代码在 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++17 开始,B{} 是聚合的,即使它是从 A 派生的,因此将为聚合创建一个临时的 A由无权访问 dtor 的用户初始化。所以 clang 拒绝编译是正确的。标准:

no virtual, private, or protected (since C++17) base classes

但是使用 () 将按照标准规定工作。

基的dtor可以是public或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

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

B();

Value Categories in C++17

Should this code fail to compile in C++17?

关于c++ - 这段代码是否会产生物化的基纯右值,它应该编译吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56497790/

相关文章:

c++ - 无法识别 main() 函数

c++ - reference_wrapper : make_pair VS Class Template Argument Deduction (CTAD)

c++ - 如何在C++中正确导航目录路径

c++ - 在 Eigen 中复制模板化函数参数

c++ - MFC 应用程序在发出终止信号的线程中挂起

如果一次性直接输入,C++ 程序将失败

c++ - 模板指针参数包

c++ - 使: execvp: gcc: Permission denied

c++ - 当用户定义的 dll 引用另一个用户定义的 dll 时出现链接器错误

c++ - std::less<void> 和指针类型