2

I'm wondering how I would go about using a variable to set the size of a bitset. For example,

// obtain file size:
fseek (rFile , 0 , SEEK_END);
numberOfBytes = ftell (rFile);
rewind (rFile);

const unsigned long long buffSize = numberOfBytes * 8;
std::bitset<buffSize> buffer;

I get a error message saying that the value of buffSize is unusable in a constant expression. I'm looking for a way to set the bitset to the size of whatever file I'm currently reading.

Kahless
  • 1,213
  • 2
  • 13
  • 31
  • 4
    You cannot use variables as template parameters, neither you can use non const variables to initialize const variables. It's a cruel world but you have to swallow that. – πάντα ῥεῖ Dec 02 '16 at 18:17
  • How would the compiler know how to size that thing if you won't tell it a constant value? Some Standard Library containers can be sized arbitrarily after compilation, others can't. Read the documentation carefully to know the difference. – tadman Dec 02 '16 at 18:19
  • May be you can get off with `std::vector` as a poor solution. – πάντα ῥεῖ Dec 02 '16 at 18:20
  • side note: why are u using C file functions? – AndersK Dec 02 '16 at 18:22

3 Answers3

8

It can't be done. The size of a std:bitset is a template parameter, so it has to be a compile-time constant.

A few choices that can/could work would be:

  1. Set an upper bound on the size, use a bitset of that size, and just ignore the extra bits.
  2. Switch to an std::vector<bool>. This has caveats, but provides roughly similar basic capabilities as a bitset.
  3. Switch to a Boost dynamic_bitset. This will let you specify the size as a parameter to the ctor, rather than a template parameter, so it doesn't need to be a compile-time constant.

There are undoubtedly other possibilities, of course. Personally, my first choice would probably be the Boost dynamic_bitset.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • `vector` would obviously take 8 times the memory though. – Mooncrater Jul 26 '19 at 06:57
  • 1
    @mooncrater: might seem obvious, but it's generally wrong. `vector` has a specialization for `bool` that uses a packed representation, so they're essentially the same size. – Jerry Coffin Jul 26 '19 at 07:19
  • Damn! That's something new! Can you lead me to some sources for this? – Mooncrater Jul 27 '19 at 05:54
  • 1
    @Mooncrater: that's been required since the 1998 standard (and it wasn't really new then). C++98, §[lib.vector.bool]/1 says: "To optimize space allocation, a specialization of vector for bool elements is provided:" (and then goes on to define the interface to the specialized class, where: "`reference` is a class that simulates the behavior of references of a single bit in vector." – Jerry Coffin Jul 27 '19 at 06:24
  • New for me though! Thanks! – Mooncrater Jul 27 '19 at 06:25
  • 1
    You're certainly welcome. You should probably also be aware that some people think providing this specialization was a mistake--it means a `vector` is different from any other vector in some subtle (and sometimes not even very subtle) ways. – Jerry Coffin Jul 27 '19 at 06:26
3

There are two different types of constants, compile time constants and everything else that is declared const. In your code you have the latter. Even though it is declared as const is is initialized with data that is not known until run time so it is not a compile time constant.

std::bitset needs to be defined with a compile time constant. Since you do not have one the compiler gives you an error. If you need a bitset defined at runtime I would suggest boost::dynamic_bitset.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
0

You can't, the size needs to be known at compile time

Eran
  • 2,324
  • 3
  • 22
  • 27