Чтобы справиться с этим затруднением, функция vector возвращает объект, который vector выглядит примерно так:
template
vector
public:
class reference {…};// Класс, генерирующий промежуточные
// объекты для ссылок на отдельные биты
reference operator[](size_type n); // operator[] возвращает
… // промежуточный объект
};
Теперь понятно, почему следующий фрагмент не компилируется:
vector
bool *pb=&v[0]; // Ошибка! Выражение в правой части относится к типу
// vector
А раз фрагмент не компилируется, vector не удовлетворяет требованиям к контейнерам STL. Да, специфика vector особо оговорена в Стандарте; да, этот контейнер
Спрашивается, почему же vector присутствует в Стандарте, если это не контейнер? Отчасти это связано с одним благородным, но неудачным экспериментом, но позвольте мне ненадолго отложить эту тему и заняться более насущным вопросом. Итак, от vector следует держаться подальше, потому что это не контейнер — но что же делать, когда вам действительно
В стандартную библиотеку входят два альтернативных решения, которые подходят практически для любых ситуаций. Первое решение — deque. Контейнер deque обладает практически всеми возможностями vector (за исключением разве что reserve и capacity), но при этом deque является полноценным контейнером STL, содержащим настоящие значения bool. Конечно, внутренняя память deque не образует непрерывный блок, поэтому данные deque не удастся передать функции C, получающей массив bool (см. совет 16), но это не удалось бы сделать и с vector из-за отсутствия переносимого способа получения данных vector. (Прием, продемонстрированный для vector в совете 16, не компилируется для vector, поскольку он зависит от возможности получения на тип элемента, хранящегося в векторе, — как упоминалось выше, vector не содержит bool.)
Второй альтернативой для vector является bitset. Вообще говоря, bitset не является стандартным контейнером STL, но входит в стандартную библиотеку C++. В отличие от контейнеров STL, размер bitset (количество элементов) фиксируется на стадии компиляции, поэтому операции вставки-удаления элементов не поддерживаются. Более того, поскольку bitset не является контейнером STL, в нем отсутствует поддержка итераторов. Тем не менее bitset, как и vector, использует компактное представление каждого элемента одним битом, поддерживает функцию flip контейнера vector и ряд других специальных функций, имеющих смысл в контексте битовых множеств. Если вы переживете без итераторов и динамического изменения размеров, вероятно, bitset хорошо подойдет для ваших целей.
А теперь вернемся к благородному, но неудачному эксперименту, из-за которого появился «псевдоконтейнер» vector. Я уже упоминал о том, что промежуточные объекты часто используются при программировании на C++. Члены Комитета по стандартизации C++ знали об этом, поэтому они решили создать vector как наглядный пример контейнера, доступ к элементам которого производится через промежуточные объекты. Предполагалось, что при наличии такого примера в Стандарте у программистов появится готовый образец для построения собственных аналогов.