【问题标题】:constexpr constructor must initialize direct base class (Visual Studio)constexpr 构造函数必须初始化直接基类 (Visual Studio)
【发布时间】:2020-09-26 10:44:40
【问题描述】:

我有别人的代码我不应该改变:

struct Parent { int thing1, thing2; };

并且想让我的继承类可用于constexpr

struct Child: public Parent
{
    constexpr Child() {}                                          //error
    constexpr Child(int t1, int t2) { thing1 = t1; thing2 = t2; } //error
    constexpr Child(const Child& c) = default;
};

当我在 Visual Studio 中编译它(使用 /std:c++-latest)时,标记的 ctors 会给出错误:

E2433: constexpr constructor must initialized direct base class

它仍然可以编译(尽管将其报告为错误,而不是警告)。它在 g++ 10 中也能正常编译(使用 -std=c++2a)。

(另外,我可以通过显式调用父级的默认 ctor 来消除错误——但我认为这不应该是一个要求?

    constexpr Child() : Parent () {}
    constexpr Child(int t1, int t2) : Parent () { thing1 = t1; thing2 = t2; }

)

那么,对于 C++20 标准,谁是对的:VS 还是 g++?是否有一种经过批准的方法可以给我的类 constexpr ctors,同时从没有 constexpr ctors 的基类继承(或合并为成员变量)?

【问题讨论】:

    标签: c++ visual-c++ c++20


    【解决方案1】:

    在 c++20 之前,您的 Parent 类不是 constexpr 可构造的,因为数据成员没有默认初始值设定项。我相信这是一个允许它编译的 gcc 错误。

    你可以像这样构造Parent constexpr:

    struct Parent { int thing1{}, thing2{}; };  // provide default values for members
    

    请注意,您可以要求Parent 的构造函数为 constexpr,如下所示:

    struct Parent { 
      int thing1, thing2; 
      constexpr Parent() = default;
    };
    

    现在 gcc 也将无法编译它。

    从 c++20 开始,通过允许在 constexpr 上下文中对普通默认可构造类型(例如ints)进行默认初始化,此限制已被删除。请参阅此paper 了解基本原理。

    所以你的代码应该在 c++20 中编译,但是与许多这样的特性一样,一些编译器可能还没有实现它。

    【讨论】:

    • 我无法重写 Parent 类——它不是我的。有没有办法给我的类 constexpr ctors,同时从没有 constexpr ctors 的基类继承(或合并为成员变量)?
    • 嗯,我不这么认为。 Parent 被明确编写为具有非 constexpr 构造函数,因此我认为您不能在事后更改其定义。首先,这将违反 ODR。您在问题中提出的修复似乎足够了,即在 Child 的 constexpr 构造函数中,显式初始化 Parent
    • clang 给出了-std=c++17 的错误,但没有给出-std=c++20 see godbolt 的错误。 C++20 中可能有一个变化,允许在 constexpr 上下文中隐式初始化 POD。
    • @IlCapitano 啊,这很有趣。我得调查一下。
    • 从c++20开始,不需要重写Parent。在 c++20 之前,您可以在问题中使用解决方法。
    猜你喜欢
    • 2019-12-24
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    相关资源
    最近更新 更多