I am trying to write a C++ template class which contains an array of bits (as a member variable). The size of the bit-array is known at compile time, so I'd really like it to be a std::bitset
, but I'm having difficulty writing an operator[]
function to set the bits.
For example, I'd like my class to start out something like this:
template<size_t N>
class bitvector
{
public:
bool operator[](size_t i) const { return bits[i]; }
bool& operator[](size_t i) { return bits[i]; }
private:
std::bitset<N> bits;
};
The getter works okay. The problem is that the std::bitset::operator[]
setter function returns a std::bitset::reference
(not a bool&
) which is itself templated. I'm not too experienced with templates, but the following attempt failed:
template<size_t K>
std::bitset<K>::reference operator[](size_t i) { return bits[i]; }
with the following error need 'typename' before 'std::bitset<K>::reference' because 'std::bitset<K>' is a dependent scope
. I tried some googling, but to no avail.
Is std::bitset
a suitable tool for this task? If so, how can I write the setter function? If not, what can I use instead? (I would still like it to be actually stored as bits, and std::vector<bool>
doesn't seem quite right, as I want the array size to be strictly fixed at compile time).
You can just return a std::bitset<N>::reference
as follows:
template<size_t N>
class bitvector
{
public:
bool operator[](size_t i) const { return bits[i]; }
typename std::bitset<N>::reference operator[](size_t i) { return bits[i]; }
private:
std::bitset<N> bits;
};
There's no need to have the additional template<size_t K>
since you can still access the original template parameter N, and under no circumstances would you want the N and your K to be different.
You need the typename
before the function's return type to tell the compiler the ::reference
is a type rather than a value.
For example:
struct Foo{
typedef int reference;
};
struct Bar{
static int reference;
};
Here Foo::reference
is a type, but Bar::reference
is a variable, without the typename
before the return type the compiler will complain as it could be that std::bitset<N>::reference
is a variable. (The compiler should have all the information it needs to work out that it isn't a value, but for some reason it is required anyway).