static_assert 中的 std::pow 触发错误 C2057?
Posted
技术标签:
【中文标题】static_assert 中的 std::pow 触发错误 C2057?【英文标题】:std::pow in static_assert triggers error C2057? 【发布时间】:2014-05-01 01:55:24 【问题描述】:Visual Studio 2013 中的以下代码导致错误 C2057:
#include <cmath>
int main()
static_assert(std::pow(2, 2) < 5, "foobar");
return 0;
错误 C2057:预期的常量表达式
如果我在 GCC -std=c++0x
下编译它可以正常工作。 http://ideone.com/2c4dj5
如果我将std::pow(2, 2)
替换为4
,它也会在Visual Studio 2013 下编译。
【问题讨论】:
Visual C++ 2013 不支持constexpr
。但即使是这样,pow
也不需要是constexpr
,因此您的代码充其量是不可移植的,并且依赖于实现扩展。
【参考方案1】:
std::pow
不是constexpr
函数。 GCC 接受您的代码的原因是因为它提供了 pow
的 builtin version,它在编译时评估函数,因为参数是已知的。如果您将-fno-builtin
标志添加到GCC 命令行,您的代码fails to compile。报错信息如预期:
错误:静态断言的非常量条件
所以,这不是 VS2013 的 bug,而是 GCC 优化的效果。 clang doesn't compile 代码。
【讨论】:
【参考方案2】:解决方法是将您自己的pow
实现为 constexpr 函数。
template<typename T>
constexpr T _pow(T x, size_t y)
return y ? x * _pow(x, y-1) : 1;
此实现非常简单,但应该适用于您的用例。
【讨论】:
以上是关于static_assert 中的 std::pow 触发错误 C2057?的主要内容,如果未能解决你的问题,请参考以下文章
标准对 std::pow、std::log 等 cmath 函数有啥看法?
c++11:为啥 std::forward 中的 static_assert 是必要的?