标准库中常见的数学函数为什么不是“常量表达式”?

11

由于某种原因,clang++(但不是 g++) 抱怨:

constexpr double invdecayf1m(double x) {
  return -log1p(-x);
}

告诉我

non-constexpr function 'log1p' cannot be used in a constant expression
  return -log1p(-x);

为什么不是所有在<cmath>中声明的常用数学函数都声明为constexpr函数”


如果需要循环计算怎么办? :) - Drax
@Drax:循环允许吗?递归肯定是可以的。(请参见我问题中的constexpr链接。) - Neil G
所以有人需要以递归的方式重写所有数学库(据我所知,不允许使用循环):D - Drax
3个回答

2

我认为唯一的原因是没有人提出将它们设为“constexpr”的建议。一般来说,这是可能的,因为它们是纯函数。实现可以使用编译器内建函数在其库中实现它们,所以不需要“真正”的实现。但是,如果没有这个提案,你不能指望这些特性有 constexpr 的实现。


1
答案在您发布的链接中:

 the function body must be either deleted or defaulted or contain only
 the following:   

....
exactly one return statement that contains only literal values, constexpr variables and functions.

那里的函数并不简单。实际上,它们相当复杂,无法作为单个返回语句实现。三角、对数和双曲线函数相当复杂,难以作为constexpr函数实现。

8
C++14将放宽对constexpr函数的限制,因此你的答案将不再有效。 - ForNeVeR
3
我更倾向于使用“困难”而非“不可能”的说法,因为只要有?:运算符和递归,你就可以实现几乎所有不需要运行时知识(内存操作)的功能。 - Drax
1
@ForNeVeR 很好。因为问题是关于c++11的。 - BЈовић
2
@BЈовић constexpr float sinh(float x) {return 0.5 * (exp(x)-exp(-x));} 现在你只需要一个 constexpr exp :D - Drax
3
这是错误的,标准并不要求std内的函数必须是实际的函数。 - K-ballo
显示剩余6条评论

1
数学库,如其名称所示<cmath>,源自于C语言,并且是在constexpr甚至没有想法的时候编写的。
为了让大多数函数成为constexpr,你需要以constexpr的方式重写整个库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接