如何克服Bitset错误

时间:2011-08-03 09:17:14

标签: c++ binary bitset

如果我写,

int a=10,b=12;
int sub = b-a;

std::bitset<8*sub> bits(bitMask);

它给我一个错误说

  

错误C2975:'_ Bit':'std :: bitset'的模板参数无效,   预期的编译时常量表达式

如何克服此错误,我想在运行时初始化bitset,是否可能? 还是有其他方法可以做到这一点?

4 个答案:

答案 0 :(得分:3)

模板参数必须是编译时常量。将模板视为代码生成器:必须在开始编译之前生成代码。您不能在“运行时”使用模板!

const unsigned int size = 10;
std::bitset<size> b;  // fine, the compiler knows what "size is"

unsigned int n; cin >> n;
std::bitset<n> c;     // doesn't make sense!

作为第一步,您应该在代码中尽可能多地说const;实际上你可能确实有编译时常量但是没有将它们声明为这样。

如果您确实需要具有动态大小的数据结构,则需要使用其他内容(例如,无符号字符向量以及按位访问器函数)。


这是一个非常简单的位设置为字符向量的实现。我不是把它包装在课堂上,如果需要的话你可以这样做:

std::vector<unsigned char> data;

bool getBit(size_t n, const std::vector<unsigned char> & data)
{
  if (data.size() * CHAR_BIT) <= n) return 0;

  return data[n / CHAR_BIT] & (1U << (n % CHAR_BIT));
}

void setBit(size_t n, std::vector<unsigned char> & data)
{
  if (data.size() * CHAR_BIT) <= n) data.resize(n / CHAR_BIT + 1, 0);

  data[n / CHAR_BIT] |= (1U << (n % CHAR_BIT));
}

// Exercise for the reader
void clrBit(size_t n, std::vector<unsigned char> & data);
void tglBit(size_t n, std::vector<unsigned char> & data);

答案 1 :(得分:2)

标准对您的问题的回答是使用std::vector<bool>,这是一个可以动态调整其大小的位集。

请注意,std::vector<bool>std::vector专业化,允许以最有效的内存方式存储位。 (这就是为什么它很糟糕:它与其他std::vector<T>的行为不同T。如果你想要std::vector bool,你可以'吨。)

接口与std::bitset 保持一致(这也很糟糕,因为使用vector的通用代码如果用bool进行实例化会破坏地狱,所以你的现有代码不应该破坏。

std::vector<bool>专业化将在下一个标准中弃用。如果您已经在使用C ++ 0x,那么正确的选择是std::dynamic_bitset。如果您坚持使用当前的C ++标准,那么std::vector<bool>就是您想要的。

答案 2 :(得分:1)

如果你想要一个......动态bitset(我知道,疯了,对吗?)你可以使用boost::dynamic_bitset

boost::dynamic_bitset<> bits(8 * sub, bitMask);

答案 3 :(得分:0)

在你的情况下,你可以在那里贴上const所以这是一个constexpr

const int a=10,b=12;
const int sub = b-a;

std::bitset<8*sub> bits;

(来自评论)您无法在运行时初始化bitset;这就是为什么它是模板参数,或编译时常量

另一种方法是使用std::vector个bools,它已经包含在具有一些自定义访问函数的类中