位掩码取决于数据类型

时间:2016-06-16 12:13:50

标签: c++ bitmask

我想应用一个位掩码来只获取位的上半部分。所以对于uint32来说就是这样:

uint32_t version_part = oldID & 0xFFFF0000;

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

鉴于存在有限数量的数据类型,我认为你可以制作if-cases(静态的,如果是?)但是我想知道是否有更好的方法来实现它。

3 个答案:

答案 0 :(得分:2)

下面的内容会解决你的目的吗?

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

答案 1 :(得分:2)

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>
T maskbits(T uid)
{
    return uid & Mask<T>::value;
}

这里的一大优点是你可以将一般情况留空以在不支持的类型上获得编译错误。当然你也可以根据自己的需要计算掩码。

答案 2 :(得分:1)

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

#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

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