平凡的默认构造函数不能是 constexpr 吗?

Nei*_*son 5 c++ constructor constexpr

看起来 C++ 标准当前阻止普通默认构造函数成为 constexpr(如果有任何非静态成员变量),因为普通默认构造函数必须什么都不做,但 constexpr 构造函数必须初始化所有内容。不幸的是,这会阻止该类型成为 POD 类型。

是否有任何解决方法可以允许类类型具有可在 constexpr 代码中使用的默认构造函数,而不会使类成为非 POD?

我可以通过向构造函数添加一个冗余参数来解决这个问题,以便 constexpr 代码可以使用非默认构造函数,但这看起来很脏,尤其是因为在我关心的情况下,初始化值是不必要的,并且都将被写入-over 在后面的代码中,所以我更喜欢一个简单的默认构造函数。例如:

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
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*ges 5

更新:自 C++20 起,简单的默认初始化可以是 constexpr:wg21.link/P1331R2

本文建议允许在 constexpr 上下文中对普通默认可构造类型进行默认初始化,同时继续禁止调用未定义的行为。简而言之,只要不读取未初始化的值,在堆和堆栈分配场景中,constexpr 中就应该允许此类状态。


普通构造函数不能是 constexpr,因为使用普通构造函数初始化的结果是未初始化的值。

插图:在这种情况下,AVal 的::值应该是多少?

struct A { int a; }

constexpr A a;
using AVal = std::integral_constant<int, a.a>;
Run Code Online (Sandbox Code Playgroud)

没有答案。