constexpr 构造函数必须初始化直接基 class (Visual Studio)

constexpr constructor must initialize direct base class (Visual Studio)

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

struct Parent { int thing1, thing2; };

并想让我继承的 class 可用于 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)。

(此外,我可以通过显式调用父级的默认构造函数来消除错误——但我认为这不是必需的?

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

)

那么,对于 C++20 标准,谁是正确的:VS 还是 g++?有没有一种批准的方法可以给我的 class constexpr 构造器,同时继承(或作为成员变量合并)一个没有 constexpr 构造器的基础 class?

在 c++20 之前,您的 Parent class 不是 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 中编译,但由于许多此类功能,某些编译器可能尚未实现它。