带运算符|=的constexpr
constexpr with operator|=
我尝试编写一个函数,该函数使用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));
}
这会导致使用gcc 4.6.1的编译时失败。
error: expression ‘(p <unknown operator> ((p >> 1) | p))’ is not a constant-expression
请注意,它在没有constexpr关键字的情况下工作。
我的问题是:
为什么这不起作用?我可以看到运算符|=不是constexpr,但它对内置类型有意义吗?
有没有一种简单的方法可以把这个函数写成constexpr?我希望它在运行时合理高效,并且我有点关心可读性。
(没有在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
函数中使用。特别是倒数第二项是"作业或复合作业"。
constexpr inline uint64_t highestBit(uint64_t p)
{
return (p & (p-1))? highestBit(p & (p-1)): p;
}
每一级递归都会清除设置的最右边的位,当最后一位被清除时,只剩下最高的位,所以它会被返回。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 多成员Constexpr结构初始化
- 一个关于在C++中重载布尔运算符的问题
- 条件constexpr函数
- 运算符C++ "delete []"仅删除 2 个前值
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- 三元运算符和 if constexpr
- std::constexpr 上下文中的可选赋值运算符
- constexpr 运算符重载使用参数的问题
- 为什么 std::array 的运算符 ==() 没有标记为 constexpr?
- 转换运算符,它引用类模板参数和 constexpr 类成员
- 将默认赋值运算符声明为 constexpr:哪个编译器是正确的?
- 对于潜在的constexpr对象,所有比较运算符都是constexpr
- 为什么 std::array 的运算符 [] 不是临时的 constexpr?
- 带运算符|=的constexpr