Эффективное использование STL | страница 19



приходится предполагать, что после операции >vector:: insert становятся недействительными все указатели и ссылки (как упоминается в совете 1, контейнер >deque обладает уникальным свойством — в некоторых случаях его итераторы могут становиться недействительными с сохранением действительных указателей и ссылок). Аналогичные рассуждения приводят к выводу, что после каждого вызова >erase все итераторы, указатели и ссылки также должны считаться недействительными.

Недостаточно? Данные контейнера не передаются через интерфейс С, поскольку данная возможность поддерживается только для >vector (совет 16). Вы не сможете создать экземпляр контейнера с типом >bool — как будет показано в совете 18, >vector не всегда ведет себя как >vector и никогда не хранит настоящие логические величины. Вы даже не можете рассчитывать на постоянное время вставки-удаления, характерное для >list, поскольку в >vector и >deque эти операции выполняются с линейной сложностью.

Что же остается после всего сказанного? «Обобщенный последовательный контейнер», в котором нельзя использовать >reserve, >capacity, >operator[], push_front, pop_front, splice и вообще любой алгоритм, работающий с итераторами произвольного доступа; контейнер, у которого любой вызов >insert и >erase выполняется с линейной сложностью и приводит к недействительности всех итераторов, указателей и ссылок; контейнер, несовместимый с языком С и не позволяющий хранить логические величины. Захочется ли вам использовать подобный контейнер в своем приложении? Вряд ли.

Если умерить амбиции и отказаться от поддержки >list, вы все равно теряете >reserve, >capacity, >push_front и >pop_front; вам также придется полагать, что вызовы >insert и >erase выполняются с линейной сложностью, а все итераторы, указатели и ссылки становятся недействительными; вы все равно теряете совместимость с С и не можете хранить в контейнере логические величины.

Даже если отказаться от последовательных контейнеров и взяться за ассоциативные контейнеры, дело обстоит не лучше. Написать код, который бы одновременно работал с >set и >map, практически невозможно, поскольку в >set хранятся одиночные объекты, а в >map хранятся пары объектов. Даже совместимость с >set и >multiset (или >map и >multimap) обеспечивается с большим трудом. Функция >insert, которой при вызове передается только значение вставляемого элемента, возвращает разные типы для >set/map и их multi-аналогов, при этом вы должны избегать любых допущений относительно того, сколько экземпляров данной величины хранится в контейнере. При работе с