位掩码:使用int和int范围的可变长度列表初始化int位掩码

时间:2013-05-03 14:06:48

标签: c++ bitmask

前言:我觉得很难将答案标记为重复而不实际检查它是否解决了问题。我之前问过这个问题,但没有成功。特别是Implementing Matlab's colon : operator in C++ expression templates class没有回答这个问题。它是固定数量的变量与变量变量数量+整数范围和整数值的可变组合。如果你仍然认为正确的方向,那么请提供一个有效的解决方案来解决我说明的问题,或者如果你不能这样做,就不要把它标记为重复。

=>在您点击重复按钮之前,请检查它是否正在回答我的问题。感谢。

我正在尝试找到最优雅的方法来定义位掩码。此位掩码是一个整数,它定义了地图上对象的可见性(32个级别,因此位0..31定义了32个级别中每个级别的可见性)。 bitmaks创建助手应该能够处理可变长度的整数列表,以及整数范围 - 以及这些的任意组合。

E.g。它可能看起来像:

int visibilityMask = CreateVisibilityMask([1..12],16,22);

我猜这个真的很难。但这不可能吗?

4 个答案:

答案 0 :(得分:1)

根据Sarien答案:

class MaskCreator
{
  public:
    MaskCreator& AddRange(int from,int to){
      for(int i= from; i<=to; ++i){
        m_list.push_back(i);
      }
      return *this;
    }

    MaskCreator& Add(int i){
      m_list.push_back(i);
      return *this;
    }

    MaskCreator& AddMulti( varargstuff ){
      m_list.push_back(i);
      return *this;
    }

    unsigned int GetMask();

  private:
    vector<int> m_list;
}

// usage:
   unsigned int mask = MaskCreator().Add(3).Add(7).AddRange(16,25).AddMulti(28,30,31).GetMask();

显然AddMulti可以替换Add;

答案 1 :(得分:0)

使它成为VisibilityMask(范围(1,12))。添加(16)。添加(22),这将很容易。

您只需要提供一个构造函数和一个Add函数,该函数具有Range对象(或两个整数)和一个int的重载。如果你返回当前对象,你可以像这样链接调用。

您还可以重载运算符&lt;&lt;或者operator()如果你想要更漂亮的语法。但我认为这不是一个好主意。我只会为输出(&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&gt

你可能会重载逗号运算符或一些这样的恶作剧,但我不推荐它。坚持使用惯用的C ++,即使它意味着Range(1,12)现在比[1..12]多4个字符。您也不应该使用可变参数函数(请参阅here)。

答案 2 :(得分:0)

可以使用varags 我不经常使用它们可以是包含载体的vararg列表吗? 如果是的话你可以这样做:

std::vector<int> SingleIndices( int vararglist)
{
  std::vector<int> vec;
  /// push all ints 
  return vec;
}

std::vector<int> Range(int from, int to)
{
  std::vector<int> vec;
  for(int i= from; i<=to; ++i){
    vec.push_back(i);
  }
  return vec;
}


int CreateVisibilityMask( vectorvarargs );

//usage:
unsigned int mask = CreateVisibilityMask(Range(1,5),SingleIndices(8,9,23), Range(25, 30));

所有这一切似乎都过于笼罩而且效率不高。

答案 3 :(得分:0)

让我想到的另一个不错的选择就是使用以下格式的var-arg int列表:

int mask = getBitMask(1, 4, 6,-10, 15, 20,-24);

然后你处理args并找到一个负数,然后这意味着最后一个数字和当前数字的abs之间的所有索引形成一个范围。

唯一的缺点是,没有语义编译时检查禁止像

这样的事情
int mask = getBitMask(-2, 4, 6); // allthough this may be valid and just mean bit 0 to 2

int mask = getBitMask(4, -6, -10);