自动生成位位置

Automatically generate bit positions

本文关键字:位置 自动生成      更新时间:2023-10-16

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

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 的解决方案将是理想的。

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

#define BIT(n) (1 << (n))
您可以使用

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

下面就可以了:

#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("%xn", one);
  printf("%xn", two);
  printf("%xn", three);
  printf("%xn", four);
  return 0;
}

程序将发出:

1
2
4
8

这个想法是第一个虚拟枚举比前一个枚举更进一步。x 是掩码,第二个虚拟人恢复值,以便下一个宏有一个很好的起点。

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

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

然后按照 H2CO3 的建议使用 std::bitset<count> 或 BIT 宏:

BIT(alpha)

Microsoft C++具有

__COUNTER__

预定义的宏,因此您可以...

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