Как заставить operator [] возвращать ссылки на отдельные биты в unsigned int? - PullRequest
0 голосов
/ 19 декабря 2011

Я делаю реализацию vector<bool>. Я сохраняю целое число без знака и использую побитовые операции, чтобы иметь вектор true и false. Моя проблема в этом; Я могу получить доступ к отдельным битам с помощью оператора [], но как мне получить ссылку на такой бит, чтобы я мог написать

Vector<bool> v(5, true);
v[3] = false;

Где-то я слышал, что вы не должны делать ссылки / указатели на отдельные биты. Краткое описание кода, который работает для получения значения бита:

...
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;
};

Итак, как вы можете вернуть какую-то ссылку, позволяющую изменить отдельные биты?

Ответы [ 4 ]

7 голосов
/ 19 декабря 2011

Вам необходимо определить прокси-объект с соответствующими перегрузками операторов, чтобы он действовал как bool&, но адресовал отдельные биты. Это то, что делает std::vector<bool>.

Примерно так:

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;
};

Как правило, я бы рекомендовал избегать подобных вещей, которые полагаются на скрытые неявные преобразования в C ++, потому что они действительно портят вашу интуицию и не очень хорошо подходят для таких вещей, как auto и decltype в C ++ 11.

4 голосов
/ 19 декабря 2011

Вы не можете сделать это, возвращая ссылку на bool. Вместо этого вам нужно создать и вернуть прокси-объект и перегрузить его оператор присваивания, например,

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) { ... }
3 голосов
/ 19 декабря 2011

Вы не можете.

Лучше всего было бы вернуть прокси-объект.

Начальная точка:

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);
};
2 голосов
/ 19 декабря 2011

Вы не можете иметь ссылки на отдельные биты.Вы можете иметь только ссылки на переменные .

Закрытие, которое вы могли бы сделать, это создать прокси-класс, который предоставляет ссылку на bool и который поддерживает внутреннюю ссылку на базовое целое числоа также необходимая механика суетливости;затем заставьте вашего [] -оператора вернуть такой прокси-объект.

...