Jarosław Gomułka
Jarosław Gomułka

Reputation: 4995

How to write bool& operator[](int index) which returns reference to single bit

Lets look at very basic implementation of Bitset.

struct Bitset {
    bool mask[32];

    bool& operator[] (int index) {
        return mask[index];
    }
};

Now I can write

Bitset bitset;
bitset[0] = 1;
std::cout << bitset[0] << "\n";

There is possible optimization. I can use unsigned int instead of bool mask[32].

struct Bitset {
    unsigned int mask;

    bool& operator[] (int index) {
        // ??
    }
};

Is it possible to write bool& operator[] (int index) with such specification ? I think std::bitset is doing something like that but i have no idea how.

Upvotes: 1

Views: 1112

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254431

No, you can't form a reference to anything smaller than char.

Instead, you could return an object that's convertible to bool, supports assignment, and knows which bit to read and write, along the lines of:

class bit_proxy
{
public:
    bit_proxy(unsigned & mask, unsigned bit) : mask(mask), index(index) {}

    operator bool() const {return mask & (1 << index);}
    void operator=(bool bit) {mask = (mask & ~(bit << index)) | (bit << index);}

private:
    unsigned & mask;
    unsigned index;
};

bit_proxy bitset::operator[](unsigned index)
{
    return bit_proxy(mask, index);
}

my_bitmask[3] = true;     // sets bit 3
bool bit = my_bitmask[3]; // gets bit 3

As noted in the comments, you might also want some compound assignment operations to more fully emulate a reference. You might also want a separate type, containing a const reference and no assignment operators, to return from a const overload of operator[].

Upvotes: 11

Ben Voigt
Ben Voigt

Reputation: 283624

No, it isn't possible. Bits inside a variable do not have unique addresses, so you can't form a pointer or reference to individual bits.

You will have to return a "smart reference" object instead of a raw reference.

Upvotes: 5

Related Questions