constexpr - 函数不能用在常量表达式中

constexpr - function cannot be used in a constant expression

我想在编译时为给定范围内的数学函数计算查找 table,然后在 运行 时从 table 检索值。我的代码如下:

#include <iostream>
#include <cmath>


template<int size>
class LookupTable {
public:
constexpr LookupTable(double xMin, double xMax) : array(), xMin(xMin), xMax(xMax), dx((xMax - xMin) / (size - 1)) {
    for(auto i = 0; i < size; ++i)
        array[i] = exp(xMin + i * dx);
}

constexpr double operator()(double x) const {
    return array[std::min(std::max(static_cast<int>((x - xMin) / dx), 0), size-1)];
}

private:
double array[size];
double xMin;
double xMax;
double dx;
};



int main() {
    const double x = 0.5;
    constexpr LookupTable<10000> table(0.0, 1.0);
    std::cout << "f(x) = " << table(x) << std::endl;  // evaluated at compile time ?
    std::cout << "f(x) = " << LookupTable<10000>(0.0, 1.0)(x) << std::endl;  // evaluated at run time ?
    return 0;
}

代码在 gcc 5.1 及更高版本上编译和 运行s,但在 Clang 3.8 上不编译。 Clang 的错误消息是:constexpr 变量 'table' 必须由常量表达式初始化并且非 constexpr 函数 'exp' 不能在常量表达式中使用。

当我删除 constexpr 时:

constexpr LookupTable<10000> table(0.0, 1.0);

然后代码在 Clang 上编译和 运行s。

我的问题是:

谢谢

这似乎是 gcc 的不符合要求的扩展,因为 exp()<cmath> 中声明时没有 constexpr

17.6.5.6 constexpr functions and constructors [constexpr.functions]

1 This standard explicitly requires that certain standard library functions are constexpr (7.1.5). An implementation shall not declare any standard library function signature as constexpr except for those where it is explicitly required. Within any header that provides any non-defining declarations of constexpr functions or constructors an implementation shall provide corresponding definitions.

如果你的 LookupTable 前面没有 constexpr,它确实会在运行时初始化。一种解决方法是将其设为 static 变量,以便您可以在启动时对其进行初始化。

如果你想要 constexpr 数学函数,你需要自己写,或者写一个标准提案,将当前的 <cmath> 库修改为 constexpr