强制constexpr在编译时进行评估

时间:2014-06-20 07:47:19

标签: c++ c++11 constexpr

#include <algorithm>

struct S
{
    static constexpr int X = 10;
};

int main()
{
    return std::min(S::X, 0);
};

如果std::min期望const int&,编译器很可能希望在某处定义S::X,即S::X的存储必须存在。

请参阅herehere

有没有办法强制编译器在编译时评估我的constexpr

原因是:

最初,我们在init优先级中早期初始化静态变量时遇到了问题。有一些struct Type<int> { static int max; };,一些全局static int x = Type<int>::max;,以及其他一些早期代码other_init使用了x。当我们更新GCC时,我们突然在x == 0中获得了other_init

我们认为我们可以通过使用constexpr来避免这个问题,因此它总是在编译时对它进行评估。

唯一的另一种方法是使用struct Type<int> { static constexpr int max(); };代替,即让它成为一个函数。

2 个答案:

答案 0 :(得分:3)

constexpr在编译时进行评估。你的问题是 由于std::min不是constexpr,所以 无论其输入如何,结果都不是const表达式 (特别是,如果使用static初始化变量 使用std::min的生命周期,它是动态初始化)。

最简单的解决方案可能是定义您自己的min, 类似的东西:

template <typename T>
constexpr T staticMin( T a, T b )
{
    return a > b ? b : a;
}

这应该导致在编译时进行全面评估,并且 静态初始化。

答案 1 :(得分:0)

对于允许作为模板值参数存在的类型,您可以引入如下数据结构:

template <typename T, T K>
struct force
{
    static constexpr T value = K;
};

用法:

force<int, std::min(S::X, 0)>::value