假设我想编写一个执行整数平方根的C ++ 1y / 14 constexpr函数:
constexpr int constexpr_isqrt(int x);
我想执行完整性检查以确保x
是非负面的:
constexpr int constexpr_isqrt(int x)
{
if (x < 0)
???
...
}
我应该在???
上面写什么?
理想情况下,如果在常量上下文中计算函数,它应该导致编译时错误,并且如果在运行时调用运行时错误(例如中止或抛出异常)。
答案 0 :(得分:11)
你很幸运,有办法!即使在C ++ 11中!使用例外:
#include <iostream>
#include <stdexcept>
constexpr int foo(int a)
{
return (a >= 0) ? a : throw std::invalid_argument("Negative!");
}
template <int n>
struct Foo
{
};
int main()
{
Foo<foo(1)> f1(); // fine, guaranteed compile time
Foo<foo(-1)> f2(); // bad, compile time error
foo(1); // fine, not necessarily at compile time
try
{
foo(-1); // fine, definitively not at compile time
}
catch ( ... )
{
}
return 0;
}
GCC对于不允许的案例有一个相当不错的错误消息:
prog.cpp: In function ‘int main()’:
prog.cpp:17:12: in constexpr expansion of ‘foo(-1)’
prog.cpp:6:63: error: expression ‘<throw-expression>’ is not a constant-expression
return (a >= 0) ? a : throw std::invalid_argument("Negative!");
对于看起来像
的C ++ 1y constexpr函数constexpr foo(int a)
{
if ( a < 0 )
{
// error!
}
++a;
//something else
return a;
}
您可以通过引入新功能来使用上述模式:
constexpr foo_positive(int a)
{
++a;
//something else
return a;
}
constexpr int foo(int a)
{
return (a >= 0) ? foo_positive(a) : throw std::invalid_argument("Negative!");
}
或者你只是写
constexpr foo(int a)
{
if ( a < 0 )
{
throw std::invalid_argument("Negative!");
}
++a;
//something else
return a;
}