我想编写一个函数HasOneBit
,即
constexpr
,我试图对此概括:
bool HasOneBit (std::uint64_t value)
{
return value != 0 && (value & (value - 1)) == 0;
}
如果类型为value
带符号整数,则会发生下溢,并且我们将最小值传递给了函数。我是否必须重载该功能8次才能实现所有可能?
以下模板函数满足所有条件(实时演示):
template <class T>
constexpr bool HasOneBit (T value)
{
static_assert (std::is_integral<T>::value && !std::is_same<T, bool>::value,
"This function should be used only with integers.");
const std::make_unsigned_t<T> unsignedValue = value;
return unsignedValue != 0 && (unsignedValue & (unsignedValue - 1)) == 0;
}
这不会调用未定义的行为,因为value
首先会转换为的未签名对应项T
。此转换不会更改的位表示value
。
我认为,该标准的相关引用是这样的(请参阅N4713,[conv.integral]#2):
如果目标类型是无符号类型,则结果值是与源整数一致的最小无符号整数(取模2 n,其中n是用于表示无符号类型的位数)。[注意:在二进制补码表示中,此转换是概念性的,并且位模式没有变化(如果没有截断)。—尾注]
一本规则的较新版本就更简单了。不确定,这是否也适用于从无符号到有符号的转换。
否则,结果是目标类型的唯一值,该唯一值与源整数模2 N一致,其中N是目标类型的宽度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句