如何检测构造函数确实是 constexpr,以便我可以利用静态初始化?

问题描述 投票:0回答:2

看这段代码:

struct NonConstexpr {
    NonConstexpr() { }
};

template <typename T>
struct Bar {
    NonConstexpr nonConstexpr;

    constexpr Bar() { }
};

struct Foo {
    Bar<void> bar;

    constexpr Foo() { }
};

在这段代码中,

Foo
的构造函数被标记为
constexpr
,但它不能出现在常量表达式中,因为它实际上无法满足this的要求。您可以在我的上一个问题中阅读详细信息。

我的问题是:我能否在编译时以某种方式检测到

Foo
的构造函数实际上不会表现得像
constexpr

我问这个的原因是,我想检测

Foo
的全局变量是否会被静态初始化(我想在上面加上
static_assert
,因为我的全局
Foo
对象必须是静态初始化)。

请注意,临时将

constexpr
添加到变量的简单解决方案不起作用,因为我的
Foo
有一个不平凡的析构函数。

c++ c++17
2个回答
2
投票

这在 C++20 中标准化为

constinit

对于以前的语言版本,Clang 具有

[[clang::require_constant_initialization]]
属性,GCC 10+ 支持
__constinit
作为扩展。


1
投票

据我所知,防止编译器默默删除 constexpr 的唯一(当前的、独立于工具链的)方法是分配给 constexpr:

struct NonConstexpr {
    NonConstexpr() { }
};

template <typename T>
struct Bar {
    NonConstexpr nonConstexpr;

    constexpr Bar() { }
};

struct Foo {
    Bar<void> bar;

    constexpr Foo() { }
};

int main()
{
    constexpr auto f = Foo();
    return 0;
}

...将无法通过

constexpr constructor calls non-constexpr function "Bar<T>::Bar() [with T=void]"

进行编译
© www.soinside.com 2019 - 2024. All rights reserved.