我如何才能检测到构造器确实是constexpr,因此可以利用静态初始化?

时间:2018-12-05 12:15:17

标签: c++ c++17

看下面的代码:

struct NonConstexpr {
    NonConstexpr() { }
};

template <typename T>
struct Bar {
    NonConstexpr nonConstexpr;

    constexpr Bar() { }
};

struct Foo {
    Bar<void> bar;

    constexpr Foo() { }
};

在此代码中,Foo的构造函数被标记为constexpr,但是它不能出现在常量表达式中,因为它实际上不能满足此要求。您可以在我的previous question中阅读其详细信息。

我的问题是:我能以某种方式检测到编译时Foo的构造函数实际上不会像constexpr那样运行吗?

我问这个原因的原因是,我想检测全局变量Foo是否将被静态初始化(我想在此变量上放置一个static_assert作为我的全局变量Foo对象必须静态初始化。)

请注意,将constexpr临时添加到变量的简单解决方案不起作用,因为我的Foo具有非平凡的析构函数。

2 个答案:

答案 0 :(得分:2)

如果使用的是Clang,请在变量上使用[[clang::require_constant_initialization]]。否则,我不知道有什么办法。

委员会正在考虑将其作为关键字进行标准化。

答案 1 :(得分: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]"

进行编译