自动生成位位置

时间:2013-01-30 13:57:24

标签: c++

我有一些看起来像这样的位掩码:

namespace bits { 
  const unsigned bit_one    = 1u << 0; 
  const unsigned bit_two    = 1u << 1; 
  const unsigned bit_three  = 1u << 2; 
  ......
  const unsigned bit_ten    = 1u << 10; 
}

除了有更多位,名称实际上是我程序的有意义标志。但有时我会删除位,添加位,重新组合相似的位等。理想情况下我可以这样做:

namespace bits { 
  const unsigned bit_one    = 1u << COUNTER; 
  const unsigned bit_two    = 1u << COUNTER; 
  const unsigned bit_three  = 1u << COUNTER; 
  ......
  const unsigned bit_ten    = 1u << COUNTER; 
}

是否有一些模板/宏会自动执行此过程?我知道__COUNTER__,但这是一个标题,所以如果它包含在使用__COUNTER__的其他来源中,它可能会中断。我正在一个前C ++ 11的框架中工作,所以在最终升级我的编译器时,一个不使用C ++ 11的解决方案将是理想的。

5 个答案:

答案 0 :(得分:1)

为什么不使用带参数的宏?

#define BIT(n) (1 << (n))

答案 1 :(得分:1)

您可以使用__LINE__宏,它是标准C和C ++的一部分。请谨慎使用并记录您的意图,以便其他人阅读代码时能理解。

#include <iostream>


namespace Bits
{
    const unsigned Base     = __LINE__ + 1;
    const unsigned BitOne   = 1u << __LINE__-Base;
    const unsigned BitTwo   = 1u << __LINE__-Base;
    const unsigned BitThree = 1u << __LINE__-Base;
}


int main(void)
{
    std::cout << Bits::BitOne   << '\n';
    std::cout << Bits::BitTwo   << '\n';
    std::cout << Bits::BitThree << '\n';
    return 0;
}

答案 2 :(得分:1)

以下将解决这个问题:

#define NEXT_MASK(x)         \
    DUMMY1_##x,              \
    x = (1U << DUMMY1_##x), \
    DUMMY2_##x = DUMMY1_##x

enum {
  NEXT_MASK(one),
  NEXT_MASK(two),
  NEXT_MASK(three),
  NEXT_MASK(four)
};

#include <stdio.h>

int main()
{
  printf("%x\n", one);
  printf("%x\n", two);
  printf("%x\n", three);
  printf("%x\n", four);
  return 0;
}

程序将发出:

1
2
4
8

这个想法是第一个虚拟枚举从之前的步骤向前迈出了一步。 x是掩码,第二个虚拟对象恢复该值,因此下一个宏将有一个良好的起点。

答案 3 :(得分:0)

经典的解决方案是字段的枚举:

enum foo_flags {
    alpha,
    beta,
    gamma,
    count
};

然后使用std::bitset<count>或BIT宏作为H2CO3建议:

BIT(alpha)

答案 4 :(得分:0)

Microsoft C ++有

__COUNTER__

预定义的宏,所以你可以......

#define NEXTBIT (1u << __COUNTER__)
namespace bits { 
  const unsigned bit_one    = NEXTBIT; 
  const unsigned bit_two    = NEXTBIT; 
  const unsigned bit_three  = NEXTBIT; 
}