避免对bitset模板进行窄化转换

Avoid narrowing conversion for bitset template

本文关键字:转换 bitset      更新时间:2023-10-16

如何以可移植的方式编写以下代码以避免窄化转换?

#include <bitset>
#include <iostream>
#include <climits>
template <typename T>
auto int_to_bitset(T x)
{
    //return std::bitset<sizeof(T)*CHAR_BIT>{x}; // does not work, narrowing conversion to unsigned type
    //return std::bitset<sizeof(T)*CHAR_BIT>{static_cast<unsigned int>(x)}; // might not have the same size as T
    //return std::bitset<sizeof(T)*CHAR_BIT>{static_cast<unsigned T>(x)}; // What I would like to do, but does not work. I've never seen so many errors.
    return std::bitset<sizeof(T)*CHAR_BIT>(x); // works, but selects unsigned long long for the constructor's parameter on my system. Can this conversion be relied on?
}
int main()
{
    std::cout << int_to_bitset<short>( 1  ) << 'n';
    std::cout << int_to_bitset<short>(-1  ) << 'n';
    std::cout << int_to_bitset       ( 1  ) << 'n';
    std::cout << int_to_bitset       (-1  ) << 'n';
    std::cout << int_to_bitset       ( 1L ) << 'n';
    std::cout << int_to_bitset       (-1L ) << 'n';
    std::cout << int_to_bitset       ( 1LL) << 'n';
    std::cout << int_to_bitset       (-1LL) << 'n';
}

生产:

0000000000000001
1111111111111111
00000000000000000000000000000001
11111111111111111111111111111111
00000000000000000000000000000001
11111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000001
1111111111111111111111111111111111111111111111111111111111111111

您可以使用std::make_unsigned:

template <typename T>
auto int_to_bitset(T x)
{
    return std::bitset<sizeof(T)*CHAR_BIT>{static_cast<std::make_unsigned_t<T>>(x)};
}

生活例子