[英]constexpr - function cannot be used in a constant expression
I want to compute a lookup table at compile time for a mathematical function in a given range and then retrieve values from the table at run time. 我想在编译时为给定范围内的数学函数计算查找表,然后在运行时从表中检索值。 My code is as follows: 我的代码如下:
#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;
}
The code compiles and runs on gcc 5.1 and above but not on Clang 3.8. 代码编译并在gcc 5.1及更高版本上运行,但不在Clang 3.8上运行。 Clang's error messages are: constexpr variable 'table' must be initialized by a constant expression and non-constexpr function 'exp' cannot be used in a constant expression. Clang的错误消息是:constexpr变量'table'必须由常量表达式初始化,非constexpr函数'exp'不能用于常量表达式。
When I remove the constexpr in: 当我删除constexpr时:
constexpr LookupTable<10000> table(0.0, 1.0);
then the code compiles and runs on Clang as well. 然后代码也编译并在Clang上运行。
My questions are: 我的问题是:
Thanks 谢谢
This appears to be a non-conforming extension of gcc since exp()
is declared without constexpr
in <cmath>
: 这似乎是gcc的不符合扩展,因为在<cmath>
没有constexpr
声明exp()
:
17.6.5.6 constexpr functions and constructors [constexpr.functions] 17.6.5.6 constexpr函数和构造函数[constexpr.functions]
1 This standard explicitly requires that certain standard library functions are constexpr (7.1.5). 1该标准明确要求某些标准库函数为constexpr(7.1.5)。 An implementation shall not declare any standard library function signature as constexpr except for those where it is explicitly required. 实现不应将任何标准库函数签名声明为constexpr,除非明确要求它。 Within any header that provides any non-defining declarations of constexpr functions or constructors an implementation shall provide corresponding definitions. 在提供constexpr函数或构造函数的任何非定义声明的任何头中,实现应提供相应的定义。
Without the constexpr
in front of your LookupTable
, it will indeed be initalized at runtime. 如果没有LookupTable
前面的constexpr
,它确实会在运行时LookupTable
。 A work-around is to make it a static
variable, so that you can initialize it at start-up time. 解决方法是使其成为static
变量,以便您可以在启动时对其进行初始化。
If you want constexpr
math functions, you need to write your own, or alternatively, write a Standard proposal that the current <cmath>
library is modified to be constexpr
. 如果你想要constexpr
数学函数,你需要编写自己的函数,或者编写一个标准的提议,将当前的<cmath>
库修改为constexpr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.