我有一些看起来像这样的位掩码:
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的解决方案将是理想的。
答案 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;
}