C ++编译时位掩码添加

时间:2016-06-24 10:40:50

标签: c++ templates c++11 bitmask compile-time-constant

我有许多要添加的位掩码(层,逻辑OR |),但由于它们是常量,我希望在编译时这样做。输入高级模板区域...

我尝试过递归:

template <uint8_t mask, uint8_t...masks>
struct MaskAdd {
    static const uint8_t value = masks | MaskAdd<masks>::value;
};

template <uint8_t mask>
struct MaskAdd {
    static const uint8_t value = mask;
};

发出以下错误:

file.cpp:3:55: error: parameter packs not expanded with ‘...’:
  static const uint8_t value = masks | MaskAdd<masks>::value;
                                                       ^
file.cpp:3:55: note:         ‘masks’
file.cpp:7:8: error: redeclared with 1 template parameter
 struct MaskAdd {
        ^
file.cpp:2:8: note: previous declaration ‘template<unsigned char mask, unsigned char ...masks> struct MaskAdd’ used 2 template parameters
 struct MaskAdd {
        ^

我也尝试过这种奇怪的语法,由(大概)对parameter packs上的cppreference页面的误解给出:

template <uint8_t...masks>
struct MaskAdd {
    static const uint8_t value = (masks | ...);
};

引发了这些错误:

file.cpp:3:43: error: expected primary-expression before ‘...’ token
     static const uint8_t value = (masks | ...);
                                           ^
file.cpp:3:43: error: expected ‘)’ before ‘...’ token

我感觉解决方案在地狱template<template<地区的某个地方,如果有人能解释那些我会感激的。

2 个答案:

答案 0 :(得分:4)

此表达式中有拼写错误:

masks | MaskAdd<masks>::value

应该是:

mask | MaskAdd<masks...>::value
// ^ no 's'          ^ the expansion compiler was talking about

然后它会抱怨该类的重新声明,所以提供一个专门化(对于一个参数):

template <uint8_t mask>
struct MaskAdd<mask> { .. };

答案 1 :(得分:0)

这是我编译时掩码的方法... 第一个模板化参数是从右边开始计数的位,第二个是向左设置为1的位数。

template <unsigned START, unsigned RANGE>
struct Mask
{
    static const size_t val = 1 << START | Mask<START + 1, RANGE - 1>::val;
};

template <unsigned START>
struct Mask<START, 0>
{
    static const size_t val = 0;
};

如果我想创建一个掩码,例如编号14(0000 1110):

unsigned mask = Mask<1, 3>::val;