Чтобы справиться с этим затруднением, функция 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
как наглядный пример контейнера, доступ к элементам которого производится через промежуточные объекты. Предполагалось, что при наличии такого примера в Стандарте у программистов появится готовый образец для построения собственных аналогов.