Эффективное использование STL | страница 20
>multimap
приходится обходиться без оператора [ ], поскольку эта функция существует только в >map
.Согласитесь, игра не стоит свеч. Контейнеры действительно отличаются друг от друга, обладают разными достоинствами и недостатками. Они не были рассчитаны на взаимозаменяемость, и с этим фактом остается только смириться. Любые попытки лишь искушают судьбу, а она этого не любит.
Но рано или поздно наступит день, когда окажется, что первоначальный выбор контейнера был, мягко говоря, не оптимальным, и вы захотите переключиться на другой тип. При изменении типа контейнера нужно не только исправить ошибки, обнаруженные компилятором, но и проанализировать весь код, где он используется, и разобраться, что следует изменить в свете характеристик нового контейнера и правил перехода итераторов, указателей и ссылок в недействительное состояние. Переходя с >vector
на другой тип контейнера, вы уже не сможете рассчитывать на С-совместимую структуру памяти, а при обратном переходе нужно проследить за тем, чтобы контейнер не использовался для хранения >bool
.
Если вы знаете, что тип контейнера в будущем может измениться, эти изменения можно упростить обычным способом — инкапсуляцией. Одно из простейших решений основано на использовании определений >typedef
для типов контейнера и итератора. Следовательно, фрагмент
>class Widget{...};
>vector
>Widget bestWidget;
>… // Присвоить значение bestWidget
>vector
>find(vw.begin(),vw.end().bestWidget) // как у bestWidget
записывается в следующем виде:
>class Widget{...};
>typedef vector
>typedef WidgetContainer:.iterator WCIterator;
>WidgetContaner vw;
>Widget bestWidget;
>WCIterator i =find(vw.begin().vw.end(),bestWidget):
Подобная запись значительно упрощает изменение типа контейнера, что особенно удобно, когда изменение сводится к простому добавлению нестандартного распределителя памяти (такое изменение не влияет на правила недействительности итераторов/указателей/ссылок).
>class Widget{...};
>template
>Specia1Anocator{...}; // необходимо использовать шаблон
>typedef vector
>typedef WidgetContainer::iterator WCIterator;
>WidgetContainer vw;// Работает
>Widget bestWidget;
>WCIterator i=find(vw.begin().vw.end().bestWidget); // Работает
Даже если вас не интересуют аспекты >typedef
, связанные с инкапсуляцией, вы наверняка оцените экономию времени. Предположим, у вас имеется объект типа