Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.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> |