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

C++ constexpr构造函数必须初始化直接基类(Visual Studio),c++,visual-c++,c++20,C++,Visual C++,C++20,我有别人的代码,我不应该修改: struct Parent { int thing1, thing2; }; 并希望使继承的类可用于constexpr: 当我在Visual Studio中使用/std:c++-latest编译此文件时,标记的CTOR会给出一个错误: E2433: constexpr constructor must initialized direct base class 尽管将此报告为错误而不是警告,但它仍然编译。它还使用-std=c++2a在g++10中编译fine

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

struct Parent { int thing1, thing2; };
并希望使继承的类可用于constexpr:

当我在Visual Studio中使用/std:c++-latest编译此文件时,标记的CTOR会给出一个错误:

E2433: constexpr constructor must initialized direct base class
尽管将此报告为错误而不是警告,但它仍然编译。它还使用-std=c++2a在g++10中编译fine

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

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

那么,对于C++20标准,谁是对的:VS,还是g++?在继承或合并一个没有常量的基类作为成员变量时,是否有一种认可的方法为我的类指定常量表达式?

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

您可以像这样使父constexpr可构造:

struct Parent { int thing1{}, thing2{}; };  // provide default values for members
struct Parent { 
  int thing1, thing2; 
  constexpr Parent() = default;
};
请注意,您可以要求父级的构造函数为constexpr,如下所示:

struct Parent { int thing1{}, thing2{}; };  // provide default values for members
struct Parent { 
  int thing1, thing2; 
  constexpr Parent() = default;
};
现在gcc也无法编译这个

在c++20中,通过允许对constexpr上下文中的int等微不足道的默认可构造类型进行默认初始化,消除了此限制。请参见此了解基本原理

因此,您的代码应该在c++20中编译,但与许多这样的功能一样,一些编译器可能还没有实现它。

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

您可以像这样使父constexpr可构造:

struct Parent { int thing1{}, thing2{}; };  // provide default values for members
struct Parent { 
  int thing1, thing2; 
  constexpr Parent() = default;
};
请注意,您可以要求父级的构造函数为constexpr,如下所示:

struct Parent { int thing1{}, thing2{}; };  // provide default values for members
struct Parent { 
  int thing1, thing2; 
  constexpr Parent() = default;
};
现在gcc也无法编译这个

在c++20中,通过允许对constexpr上下文中的int等微不足道的默认可构造类型进行默认初始化,消除了此限制。请参见此了解基本原理


因此,您的代码应该在c++20中编译,但与许多此类功能一样,一些编译器可能尚未实现它。

我无法重写父类-它不是我的。有没有一种方法可以给我的类指定constexportors,同时继承或合并一个没有constexportors的基类作为成员变量?嗯,我不这么认为。Parent被显式地编写为具有非constexpr构造函数,因此我认为您不能在事后更改它的定义。首先,这将违反ODR。您在问题中提出的修复似乎足够了,即在Child的constexpr构造函数中,显式初始化Parent.clang给出了一个错误-std=c++17,而不是-std=c++20。C++20中可能有一个变化,允许在constexpr上下文中隐式初始化POD。@IlCapitano啊,这很有趣。我必须研究一下。从c++20开始,您不需要重写父级。在c++20之前,你可以在你的问题中使用变通方法。我不能重写父类-它不是我的。有没有一种方法可以给我的类指定constexportors,同时继承或合并一个没有constexportors的基类作为成员变量?嗯,我不这么认为。Parent被显式地编写为具有非constexpr构造函数,因此我认为您不能在事后更改它的定义。首先,这将违反ODR。您在问题中提出的修复似乎足够了,即在Child的constexpr构造函数中,显式初始化Parent.clang给出了一个错误-std=c++17,而不是-std=c++20。C++20中可能有一个变化,允许在constexpr上下文中隐式初始化POD。@IlCapitano啊,这很有趣。我必须研究一下。从c++20开始,您不需要重写父级。在c++20之前,您可以在问题中使用变通方法。