我尝试使用C++0x常量input编写一个函数,该函数返回一个仅包含输入集最高位的整数。
constexpr inline uint64_t
get_highest_bit(uint64_t p)
{
return
(p|=(p>>1)),
(p|=(p>>2)),
(p|=(p>>4)),
(p|=(p>>8)),
(p|=(p>>16)),
(p|=(p>>32)),
(p-(p>>1));
}这会导致使用gcc 4.6.1时出现编译时故障。
error: expression ‘(p <unknown operator> ((p >> 1) | p))’ is not a constant-expression请注意,它在没有constexpr关键字的情况下工作。
我的问题是:
为什么这不起作用?我可以看到operator|=不是常量表达式,但是它对于内置类型有关系吗?
有没有一种简单的方法把这个函数写成一个常量?我希望它在运行时是合理有效的,并且我有点关心可靠性。
发布于 2011-07-23 23:55:47
(没有在GCC上测试,因为我没有4.6,但我已经验证了算法是正确的。)
要使用constexpr,您不能有分配。因此,您通常必须使用递归以函数形式编写代码:
#include <cstdint>
#include <climits>
constexpr inline uint64_t highestBit(uint64_t p, int n = 1) {
return n < sizeof(p)*CHAR_BIT ? highestBit(p | p >> n, n * 2) : p - (p >> 1);
}
int main() {
static_assert(highestBit(7) == 4);
static_assert(highestBit(5) == 4);
static_assert(highestBit(0x381283) == 0x200000);
return 0;
}您可以查看C++0x§expr.const/2,查看哪些表达式不能在constexpr函数中使用。特别是,倒数第二项是“一个赋值或复合赋值”。
发布于 2011-07-24 00:02:07
constexpr inline uint64_t highestBit(uint64_t p)
{
return (p & (p-1))? highestBit(p & (p-1)): p;
}每一级递归都会清除被设置的最右边的位,当最后一位被清除时,只剩下最高的位,所以它被返回。
https://stackoverflow.com/questions/6801347
复制相似问题