位掩码取决于数据类型

Bitmask depending on data type

我想应用位掩码以仅获取上半位。所以对于 uint32 它将是这样的:

uint32_t version_part = oldID & 0xFFFF0000;

当数据类型被硬编码时这一切都很好,但如果这是一个模板化函数并且我想提供一个任意数据类型(uint8_t、uint16_t、...)我想要按比例调整位掩码的大小(0xF0、0xFF00、...),最好在编译时调整。

考虑到数据类型的数量是有限的,我想你可以做 if-cases(静态 if's?),但我想知道是否有更好的方法来做到这一点。

下面的内容是否解决了您的目的?

template<typename T>
T maskbits(T oldID)
{
    const size_t SZ = sizeof oldID * CHAR_BIT;
    const T mask = (static_cast<T>((1ULL << (SZ / 2)) - 1ULL)) << (SZ / 2);
    return oldID & mask;
}

Mohit Jain 的回答很好。但是由于您使用的是模板,您还可以使用模板专业化来做一些事情:

/* general case */
template<typename T> class Mask {  };

/* specific cases */
template<> class Mask<uint16_t> {public: static const uint16_t value = 0xFF00; };
template<> class Mask<uint32_t> {public: static const uint32_t value = 0xFFFF0000; };
/* etc. */

template<typename T>
constexpr T maskbits(T uid)
{
    return uid & Mask<T>::value;
}

最大的好处是您可以将一般情况留空,以便在不受支持的类型上出现编译错误。当然你也可以让那个计算掩码,这取决于你的需要。

也许你可以试试这个,它适用于任何整数大小。

#include <iostream>

template<typename T>
T mask(T a = 0) {
    return (~T(0)) << 4*sizeof(T);
}

int main()
{
    unsigned char v = mask<unsigned char>();
    int v2 = mask(32);
    std::cout << "v = 0x" << std::hex << (unsigned int)v << std::endl;
    std::cout << "v2 = 0x" << std::hex << (unsigned int)v2 << std::endl;
}

输出为:

v = 0xf0
v2 = 0xffff0000

编辑:我刚刚检查并启用了优化,编译器可以在编译时生成掩码