Constexpr数学函数

aar*_*man 56 c++ cmath constexpr c++11

从这个页面中可以看出,c ++ 11中的数学函数似乎都没有使用constexpr,而我相信所有这些函数都可以.所以这给我留下两个问题,一个是他们为什么选择不使函数constexpr.对于像sqrt我这样的函数来说,两个人可能会编写我自己的constexpr,但是像sin或cos这样的东西会比较棘手,所以它就在那里.

Seb*_*edl 57

实际上,由于旧的和恼人的遗产,几乎没有数学函数可以constexpr,因为它们都具有设置errno各种错误条件的副作用,通常是域错误.

  • 一个函数可以是constexpr,有时仍然抛出等.一个double的值可能取决于舍入模式,但是为constexpr情况做了适应.`errno`真的不是一个好理由. (4认同)
  • @MarcGlisse投掷和'errno`是两个非常不同的野兽.指定C标准数学函数来修改`errno`,而不是抛出异常.所以我不明白你的观点. (4认同)
  • 如果结果不准确,则指定@SebastianRedl Addition设置FE_INEXACT.但是,添加仍然是constexpr.这对你来说更接近`errno`的情况吗? (2认同)
  • 它接近,除了在C99中我没有找到这样的规范,更不用说在C++ 11中.最接近的是参考C99附录F中的ISO 60559操作.但是,C++只引用C的库子句,因此本附件在C++中没有规范作用.我不认为C++有任何要求添加有副作用.特别注意在C++ 11第5节介绍中没有任何"简约"浮点运算,它们在C99的等效部分中. (2认同)

Ada*_*zaj 9

来自B. Stroustrup的"The C++ Programming Language(4th Edition)",描述了C++ 11:

"要在编译时进行评估,函数必须非常简单:constexpr函数必须由单个return语句组成;不允许循环,也不允许局部变量.此外,constexpr函数可能没有副作用."

这意味着它必须是内联的,没有for,while和if语句和局部变量.副作用也是禁止的(例如:改变errno).另一个问题是大多数数学函数都是FPU指令,它们没有用纯c/c ++表示(它们是用汇编代码编写的).这就是为什么非cmath函数被声明为constexpr.

  • 这在C++ 14中已不再适用. (25认同)
  • @AdamSzaj constexpr函数(甚至是c ++ 11)已经完成了,所以我没有看到你提出的问题,这里是[contexpr sqrt]的一个例子(https://github.com/aaronjosephs/constexpr) /blob/master/constexprsqrt.cpp)我写了一会儿 (3认同)
  • 非常好,但尝试`awsome :: sqrt(3e13)`.您是否尝试过实现sin,cos,tanh或类似功能?我知道有这些函数的算法,但你认为`constexpr_sin(x)== sin(x)`? (2认同)

Lak*_*arg 5

从这个页面注意到,c++11 中的数学函数似乎都没有使用 constexpr,而我相信它们都可以使用。所以这给我留下了两个问题,一个是他们为什么选择不将函数设为 constexpr。

Sebastian RedlAdam Szaj很好地回答了这部分,因此不会添加任何内容。

对于像 sqrt 这样的函数,还有两个我可能可以编写自己的 constexpr,但是像 sin 或 cos 这样的东西会更棘手,所以就在它周围。

是的,您可以使用这些函数的泰勒级数展开来编写自己的 constexpr sin, cos 版本。看看这个超级酷的 github repo,它实现了几个数学函数作为 constexpr 函数Morwenn/static_math

  • 不是很酷:尝试计算`smath::cos(20.)`。余弦大于 3...实现一个像样的非 `constexpr` 触发函数已经够难的了,更不用说 `constexpr` 了。 (3认同)