3

Is it possible to have two definition of operator[] for the following two cases?

  • My_bit_array[7] = true;

  • bool x = My_bit_array[0];

This is useful because reading a bit and toggling one of the 8 bits of a byte (uint8_t) are different. These two cases would require two different definitions.

hamster on wheels
  • 2,771
  • 17
  • 50

2 Answers2

3

It's quite simple. It should be implemented using proxy object, as it was already mentioned in comments. Something like this, I suppose:

#include <iostream>
#include <cstddef>

using namespace std;

struct proxy_obj;

struct my_bit_array
{
    uint8_t bit_array_;

    proxy_obj operator[](int n);
};

struct proxy_obj
{
    my_bit_array& my_bit_array_;
    int n_;

    proxy_obj(my_bit_array& bit_array, int n) 
        : my_bit_array_(bit_array), n_(n) {}

    proxy_obj& operator=(bool b)
    {
        uint8_t set_mask = 0x01 << n_;

        if(b) my_bit_array_.bit_array_ |= set_mask;
        else  my_bit_array_.bit_array_ &= (~set_mask);

        return *this;
    }

    operator bool(){ return my_bit_array_.bit_array_ & (0x01 << n_); }
};

proxy_obj my_bit_array::operator[](int n)
{
    return proxy_obj(*this, n);
}

int main() {
    my_bit_array bit_set;

    bit_set[0] = false;
    bool b = bit_set[0];
    cout << b << endl;

    bit_set[3] = true;
    b = bit_set[3];
    cout << b << endl;

    return 0;
}
Alex Chudinov
  • 654
  • 1
  • 6
  • 12
0

you can overload subscript operator "[]" to return the address of element to be able to assign to.

you can't return a reference to a bit because bits don't have addresses the smallest addressable variable is 1 byte (bool or char) which consists of 8 bits.

#include <iostream>
using namespace std;

class Byte
{   
    public:
        Byte(bool[], int);
        ~Byte() {delete[] itsBits;}

        bool& operator[](int);

    private:

        bool* itsBits;
        int  itsLength;
};

Byte::Byte(bool bits[], int length) : 
    itsLength(length)
{
    itsBits = new bool[itsLength];
    for(int i(0); i < itsLength; i++)
        itsBits[i] = bits[i];
}

bool& Byte::operator [](int index)
{
    if(index < 0 || index > itsLength)
        return itsBits[0];
    else
        return itsBits[index];
}

int main()
{

    bool bArray[] = {true, false, true, true, false, true, false, true};
    Byte theByte(bArray, 8);

    cout << theByte[2] << endl;

    theByte[2] = false; // invoking bool& operator[] it returns a reference the 3rd element in array so we can assign to it value

    cout << theByte[2] << endl;
    cout << theByte[6] << endl; 

    for(int i(0) ; i < 8; i++)
        cout << theByte[i] << " "; 

    cout << endl << endl << endl;
    return 0;
}
Raindrop7
  • 3,889
  • 3
  • 16
  • 27
  • This is just an array of `bool`, not at all the same as accessing individual bits in a byte. – Ben Voigt Oct 10 '16 at 21:31
  • Also the comments are wrong, the `cout` lines will not invoke the `const` member. – Ben Voigt Oct 10 '16 at 21:32
  • @BenVoigt I know that it is array of bools in his case this the only way to do so because. how can you return an "address" of bit? – Raindrop7 Oct 10 '16 at 21:39
  • 2
    I know you've already seen the comments under the question because you participated in them. So you know that both `std::vector` and `std::bitset` were mentioned. These do return a referent (not a C++ reference, but a locator object, rather like a functor is not a function but can be called like one, this locator object can be used to read or mutate its target even though it is not a pointer or reference) – Ben Voigt Oct 10 '16 at 21:48