琐碎的默认构造函数不能是 constexpr?

Trivial default constructor can't be constexpr?

本文关键字:constexpr 不能 构造函数 默认      更新时间:2023-10-16

看起来C 标准当前可以防止微不足道的默认构造函数为constexpr(如果有任何非静态成员变量),因为一个琐碎的默认构造函数必须什么都不做,但是constexpr constructor却不执行必须初始化所有内容。不幸的是,这阻止了类型是POD类型。

是否有任何解决方法可以允许类类型具有可以在constexpr代码中使用的默认构造函数,而无需进行类非pod?

我可以通过向构造函数添加冗余参数来解决它,以便ConstexPR代码可以使用非默认构造函数,但这似乎很脏,尤其是因为在我关心的情况下,初始化的值是不必要的,并且将会所有这些都在以后的代码中写成,因此我更喜欢一个微不足道的默认构造函数。例如:

struct A {
    int a;
    // Non-default constructors necessitate an explicit default
    // constructor if default constructor is to exist
    constexpr A(int b) : a(b) {}
#if 1 // non-POD
    // constexpr default constructor must initialize everything,
    // but this makes A non-POD.
    constexpr A() : a(0) {}
#else // Workaround
    A() = default;
    struct UnnecessaryClass {};
    constexpr A(UnnecessaryClass) : a(0) {}
#endif
};
constexpr void someConstexprFunction(ClassThatADoesntKnowAbout& t) {
#if 1 // non-POD
    A a;             // I'd prefer this not be initialized yet,
#else // Workaround
    A a(A::UnnecessaryClass());
#endif
    t.initializeA(a) // because it's initialized here.
    // It doesn't make a difference when it's run at compile-time,
    // but the redundant initialization is rather unfortunate if it's
    // done at run-time.
}
void someNonConstexprFunction() {
    A *pa = new A[1000000]; // array is redundantly initialized in non-POD case
    ... // Other downsides of non-POD types, too
}

更新:自C 20:wg21.link/p1331r2

,可以是constexpr

本文提出了允许在constexpr上下文中的默认默认构造类型的默认初始化继续禁止调用不确定的行为。简而言之,只要不读取非初始化的值,在堆和堆栈分配的方案中,应允许在constexpr中进行状态。


一个琐碎的构造函数不能成为constexpr,因为用微不足道的构造函数初始化的结果是一个非初始化的值。

插图:在这种情况下,aval的值应该是什么?

struct A { int a; }
constexpr A a;
using AVal = std::integral_constant<int, a.a>;

没有答案。

不仅不能在 constexpr上下文中使用琐碎的构造函数,而且也不能琐碎地构造内置类型。

constexpr评估实现了C 的有限子集,该子集不包括非初始化值。因此,他们被禁止。

问题可能并不是很难获得POD类,但是Pods不做您想要的。