c++11
I tried to write a function, which returns an integer with only the highest bit of the input set, using a C++0x constexpr.
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));
}
This gives a compile-time failure using gcc 4.6.1.
error: expression ‘(p <unknown operator> ((p >> 1) | p))’ is not a constant-expression
Note that it works without the constexpr keyword.
My questions are:
Why does this not work? I can see that operator|= is not a constexpr, but does it matter for built-in types?
Is there an easy way to write this function as a constexpr? I would like it to be reasonable efficient at runtime, and I care a bit about readibility.
(Not tested on GCC because I don't have 4.6, but I've verified that the algorithm is correct.)
To use constexpr
you must not have assignments. Therefore, you often have to write in functional form with recursion:
#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;
}
You can check C++0x §[expr.const]/2 to see what expressions cannot be used in a constexpr
function. In particular, the second to last item is "an assignment or a compound assignment".
constexpr inline uint64_t highestBit(uint64_t p)
{
return (p & (p-1))? highestBit(p & (p-1)): p;
}
递归的每一级都会清除已设置的最右边的位,当最后一位被清除时,只剩下最高位,所以它被返回。
链接地址: http://www.djcxy.com/p/68360.html上一篇: 强制在编译期间评估常量表达式
下一篇: C ++ 11