C++ 如何检查整数中是否正好设置了一位?

C++ 如何检查整数中是否正好设置了一位?,c++,type-conversion,integer,C++,Type Conversion,Integer,我想写一个函数HasOneBit,它 接受任何整数类型(有符号或无符号,8到64位) isconstexpr 不调用未定义的行为 我试图概括这一点: bool HasOneBit (std::uint64_t value) { return value != 0 && (value & (value - 1)) == 0; } 如果value的类型是一个有符号整数,那么这个下溢,我们将最小的值传递给函数。我是否必须将函数重载8次才能实现所有可能性?以下模板函

我想写一个函数
HasOneBit
,它

  • 接受任何整数类型(有符号或无符号,8到64位)
  • is
    constexpr
  • 不调用未定义的行为
我试图概括这一点:

bool HasOneBit (std::uint64_t value)
{
    return value != 0 && (value & (value - 1)) == 0;
}

如果
value
的类型是一个有符号整数,那么这个下溢,我们将最小的值传递给函数。我是否必须将函数重载8次才能实现所有可能性?

以下模板函数满足所有条件():

模板
constexpr bool HasOneBit(T值)
{
静态断言(std::is_integral::value&!std::is_same::value,
“此函数只能用于整数。”);
const std::make_unsigned_t unsignedValue=value;
返回unsignedValue!=0&&(unsignedValue&(unsignedValue-1))==0;
}
这不会调用未定义的行为,因为
value
首先转换为
t
的无符号对应项。此转换不会更改
值的位表示形式

我认为,该标准的相关引用如下(见[conv.integral]#2):

如果目标类型是无符号的,则结果值是与源整数全等的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。[注:在2的补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。-结束注]

A更简单。不确定这是否也适用于无符号到有符号的转换

否则,结果是与源整数模2N全等的目标类型的唯一值,其中N是目标类型的宽度

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;
}