看这段代码:
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++20 中标准化为
constinit
。
对于以前的语言版本,Clang 具有
[[clang::require_constant_initialization]]
属性,GCC 10+ 支持 __constinit
作为扩展。
据我所知,防止编译器默默删除 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]"
进行编译