这是我使用的一个技巧,它非常方便位掩码测试某个位是否已设置或设置/重置位。我想它可能对你有很大帮助。(有时我会自暴自弃。)
template <std::size_t bitIndex, typename T>
bool get_integer_bit(const T num)
{
// Make sure what was passed in is something ilke an int or long.
static_assert(std::numeric_limits<T>::is_integer, "Numeral argument must be an integer type.");
// Don't go out of bounds of the size of the number.
static_assert(bitIndex < std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed, "bitIndex is out of bounds for type T");
static_assert(bitIndex >= 0, "bitIndex is out of bounds for type T");
// Rip the bit out of the number.
return ((0x1 << bitIndex) & num) != 0;
}
template <std::size_t bitIndex, typename T>
void set_integer_bit(T& num, const bool bitValue)
{
// Make sure what was passed in is something ilke an int or long.
static_assert(std::numeric_limits<T>::is_integer, "Numeral argument must be an integer type.");
// Don't go out of bounds of the size of the number.
static_assert(bitIndex < std::numeric_limits<T>::digits + std::numeric_limits<T>::is_signed, "bitIndex is out of bounds for type T");
static_assert(bitIndex >= 0, "bitIndex is out of bounds for type T");
// Set the bit into the number.
if (bitValue)
num |= (0x1 << bitIndex); // Set bit to 1.
else
num &= ~(0x1 << bitIndex); // Set bit to 0.
}
而对于使用...
// Test get_integer_bit.
std::cout << set_integer_bit<0>(1); // Pulls the first (0th) bit out of the integer 1. Result should be 1
std::cout << set_integer_bit<1>(1); // Pulls the second bit out of the integer 1. Result should be 0
std::cout << set_integer_bit<33>(2); // error C2338: bitIndex is out of bounds for type T
// Test set_integer_bit.
std::cout << get_integer_bit<0>(test); // Should be 0.
set_integer_bit<0>(test, 1); // Set the first (0th) bit to a 1 (true).
std::cout << get_integer_bit<0>(test); // Should be 1, we just set it.
这适用于各种大小的 int,并且当位的索引超出所提供类型的范围时,它的好处是在编译时抱怨。但是,如果您正在寻找更多的东西,并且想要更动态地访问类型的位,那么您需要使用std::bitset