Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++ FAQ > Элементы контейнера vector<bool>


Автор: Baseg 09.04.06, 00:57
Известно, что vector<bool> -- это специализация vector, в которой используется побитовая адресация. Т.е. имитируется адресация одного бита. В то же время, обычный указатель не может адресовать единицу памяти, меньшую чем байт. Это влечёт некоторые последствия. Например, нельзя рассматривать bool* как итератор для vector<bool>, а следующий код, который корректен для всех векторов, кроме vector<bool>, не будет компилироваться:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    vector <bool> v;
    bool *pBool = &v[0];

Однажды я столкнулся с проблемой ссылок и указателей на элементы vector<bool>. Сейчас я расскажу, как я вышел из ситуации.
В разрабатываемом мной приложении был класс, содержащий vector<bool> в секции private. Для чтения элементов этого вектора использовался оператор []:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class BitSet {
    private:
       std::vector<bool> rep;
    public:
       explicit BitSet(const unsigned size): rep(size) {}
       bool operator[](const unsigned i) const;
    };
     
    bool BitSet::operator[](const unsigned i) const {
       return rep[i];
    }

Проблема проявила себя, когда я захотел использовать [] для записи в rep. Сначала я написал так
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    bool& BitSet::operator[](const unsigned i) {
       return rep[i];
    }

что, естественно, оказалось неправильно. Т.к. bool& и ссылка на элемент vector<bool> это разные типы.
Выход из ситуации следующий
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::vector<bool>::reference BitSet::operator[](const unsigned i) {
       return rep[i];
    }

std::vector<bool>::reference это прокси-класс, который ведет себя как ссылка на бит.
Теперь в коде, использующем класс BitSet, можно было написать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    BitSet bs(100);
    bs[0]=true;
    bs[1]=bs[0];

Получить указатель на элемент vector<bool> можно следующим образом
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
       std::vector<bool>::reference* p = &rep[2];
       *p = true;

Однако, std::vector<bool>::reference* по-прежнему нельзя рассматривать как итератор для vector<bool>

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)