我试图用 C++ 编写一个在编译时评估的日志函数。我希望只有当输入是 2 的幂时代码才能编译并给出答案。为了实现这一点,我需要某种方法在编译时在 constexpr 函数中执行检查。
我想要以下行为:
constexpr int a = logBase2(16); // should equal 4
constexpr int b = logBase2(42); // should not compile, input is not a power of 2
constexpr int c = logBase2(-1); // should also not compile
我尝试了以下代码:
constexpr bool isPowerOf2(int x) {
return (x > 0) && ((x & (x - 1)) == 0);
}
constexpr int logBase2(int x) {
static_assert(isPowerOf2(x), "Input must be a power of 2");
int result = 0;
while ((x & 1) == 0) {
x >>= 1;
result++;
}
return result;
}
当然这不能编译,因为参数 x 不能保证是 constexpr:constexpr 只是意味着该函数可以在编译时被评估。
我需要这样的东西:
constexpr bool isPowerOf2(int x) {
return (x > 0) && ((x & (x - 1)) == 0);
}
constexpr int logBase2(constexpr int x) { // x must be able to be evaluated at compile time
static_assert(isPowerOf2(x), "Input must be a power of 2");
int result = 0;
while ((x & 1) == 0) {
x >>= 1;
result++;
}
return result;
}
但这不是有效的 C++。有什么方法可以完成这个或类似的事情吗?
如果出现“错误”,你可能会
throw
,那么你将会遇到编译错误
constexpr bool isPowerOf2(int x) {
return (x > 0) && ((x & (x - 1)) == 0);
}
constexpr int logBase2(int x) {
if (!isPowerOf2(x)) {
throw std::runtime_error("Input must be a power of 2");
}
int result = 0;
while ((x & 1) == 0) {
x >>= 1;
result++;
}
return result;
}
然后
constexpr int b = logBase2(42); // not compile
constexpr int c = logBase2(-1); // not compile