开发者

How to over come Bitset error [duplicate]

开发者 https://www.devze.com 2023-03-25 18:09 出处:网络
This question already has answers here: Define bitset size at initialization? (7 answers) Closed 5 years ago.
This question already has answers here: Define bitset size at initialization? (7 answers) Closed 5 years ago.

if i write,

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

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

it is giving me an error saying

error C2975: '_Bits' : invalid template argument for 'std::bitset', expected compile-time constant expression

how to over come this error, i want to init开发者_如何学Pythonialize bitset at run time, is it possible? or there any other way to do this?


Template parameters must be compile-time constants. Think of a template as a code generator: The code has to be generated before you start compiling. You cannot use templates "at runtime"!

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!

As a first step you should say const as much as possible in your code; it's possible that you actually do have compile-time constants but aren't declaring them as such.

If you really need a data structure with dynamic size, you need to use something else (e.g. a vector of unsigned chars along with a bitwise accessor function).


Here's a very simple implementation of a bit set as a vector of chars. I'm not wrapping this in a class, you can do that if that's needed:

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);


The Standard's anwser to your question is to use std::vector<bool>, which is a bit set which can dynamically accomodate its size.

Please keep in mind that std::vector<bool> is a specialization of std::vector which is allowed to store bits in the most memory efficient way. (This is why it sucks: it doesn't behave like std::vector<T> for other Ts. If you want a real std::vector of bool, you can't.)

The interface is kept identical to std::bitset (this also sucks, because generic code using vector will break hell if instantiated with bool), so your existing code shouldn't break.

The std::vector<bool> specialization will be deprecated in the next standard. If you are already using C++0x, the correct alternative is std::dynamic_bitset. If you are stuck with the current C++ standard, then std::vector<bool> is what you want.


You can use boost::dynamic_bitset if you want a... dynamic bitset (I know, crazy, right?).

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


In your case, you can just stick a const on there so it's a constexpr:

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

std::bitset<8*sub> bits;

(From comment) You can't initialize a bitset at runtime; that's why it's a template argument, or compile-time constant

An alternative would be to use a std::vector of bools which has been wrapped in a class with some custom access functions

0

精彩评论

暂无评论...
验证码 换一张
取 消