Reputation: 143
I'm making a vector<bool>
implementation. I save an unsigned int and use bitwise operations to have a vector of true and false. My problem is this; I can access individual bits by operator[], but how do I get a reference to such a bit so I can write
Vector<bool> v(5, true);
v[3] = false;
Somewhere I heard that you shouldn't do references/pointers to individual bits. A summary of the code, that works for retrieving bit value:
...
unsigned int arr; // Store bits as unsigned int
unsigned int size_vec; // The size of "bool vector"
...
bool& Vector<bool>::operator[](unsigned int i) {
if (i>=vec_size || i<0) {
throw out_of_range("Vector<bool>::operator[]");
}
int index = 1 << (i-1);
bool n = false;
if (index & arr) {
n=true;
}
return n;
};
So, how can you return some sort of reference making it possible to change the individual bits?
Upvotes: 0
Views: 213
Reputation: 54270
You need to define a proxy object with the appropriate operator overloads so that it acts like bool&
but addresses individual bits. This is what std::vector<bool>
does.
Something like this:
struct Bit
{
public:
typedef unsigned char byte;
Bit(byte& _byte, byte _bit)
: m_byte(_byte), m_mask(1u << _bit)
{}
operator bool() const
{
return m_byte & m_mask;
}
Bit& operator=(bool x)
{
m_byte = x ? m_byte | m_mask : m_byte & ~m_mask;
return *this;
}
private:
byte& m_byte;
const byte m_mask;
};
Generally I would recommend avoiding things like this that rely on sneaky implicit conversions in C++ because it really messes with your intuition, and it doesn't play nicely with things like auto
and decltype
in C++11.
Upvotes: 7
Reputation: 53037
You can't.
You're best bet would be to return a proxy object.
Starting point:
struct bit {
bit(Vector<bool>* vec, size_t pos);
bit& operator=(const bool& b);
operator bool();
Vector<bool>* vec;
size_t pos;
};
bit Vector<bool>::operator[](size_t pos) {
return bit(this, pos);
};
Upvotes: 3
Reputation: 129764
You cannot do that by returning a reference to bool. You need to create and return a proxy object instead, and overload its assignment operator, something like
struct bit_access_proxy {
bit_access_proxy(int& carrier, int bit) { ... }
operator bool() const {
// return the value of the bit
}
bit_access_proxy& operator=(bool new_bit) {
// set the value of the bit
}
};
bit_access_proxy Vector<bool>::operator[](int i) { ... }
Upvotes: 4
Reputation: 476980
You cannot have references to individual bits. You can only have references to variables.
The closes thing you could do is make a proxy class which exposes a reference to a bool
and which maintains an internal reference to the base integer as well as the necessary bitfiddling mechanics; then make your []
-operator return such a proxy object.
Upvotes: 2