简体   繁体   English

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

[英]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: 我的问题是:

  • What is the meaning of the error message "function 'exp' cannot be used in a constant expression" ? 错误消息“function'exp'不能用于常量表达式”是什么意思? And is there a workaround? 有解决方法吗?
  • Does that mean that when I declare LookupTable<10000> table(0.0, 1.0); 这是否意味着当我声明LookupTable <10000>表(0.0,1.0)时; without the constexpr, then the table precomputations happen at run-time? 如果没有constexpr,那么表预计算会在运行时发生吗? I am using an online compiling tool so I do not have an option to benchmark the code right now. 我正在使用在线编译工具,所以我现在没有选择对代码进行基准测试。
  • I would like to generalize the code and templatize the mathematical function. 我想概括代码并模拟数学函数。 It works fine with functors but is it possible to use lambdas? 它可以与仿函数一起使用,但是可以使用lambdas吗?

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.

相关问题 MSVC constexpr函数'xyz'不能导致常量表达式 - MSVC constexpr function 'xyz' cannot result in a constant expression 什么决定了 constexpr function 是否是常量表达式? - What determines whether a constexpr function is a constant expression? 返回常量表达式不需要constexpr函数吗? - A constexpr function is not required to return a constant expression? g ++抱怨constexpr函数不是常量表达式 - g++ complains constexpr function is not a constant expression 使用从未打算在常量表达式中使用的 constexpr 变量是否有好处? - Are there benefits to using a constexpr variable that is never intended to be used in a constant expression? Function 参数未知值不能用于常量表达式 - Function parameter with unknown value cannot be used in a constant expression 生成constexpr字符串表,不能生成常量表达式 - Generate constexpr string table, cannot result in a constant expression 如果结构化绑定不能是constexpr,为什么它们可以在constexpr函数中使用? - If structured bindings cannot be constexpr why can they be used in constexpr function? 永远不会计算为常量表达式的 lambda() 可以是 C++ 中的 `constexpr` 函数吗? - Can lambda() that never evaluates to a constant expression be a `constexpr`-function in C++? `static constexpr` function 在常量表达式中调用是...错误? - `static constexpr` function called in a constant expression is...an error?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM