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 T
s. 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
精彩评论