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



. Такие типы называются зависимыми типами. Небольшой пример поможет вам лучше понять, о чем идет речь. Предположим, вы пишете шаблон функции, которая получает контейнер STL и возвращает результат проверки условия «последний элемент контейнера больше первого». Одно из возможных решений выглядит так:

>template

>bool latGreaterThanFirst(const С& container)

>{

>if(container.empty()) return false:

>typename C::const_iterator begin(container.begin());

>typename C::const_iterator end(container.end());

>return *--end > *begin;

>}

В этом примере локальные переменные >begin и >end относятся к типу >С::const_iterator, зависящему от формального параметра С. Поскольку тип >С:: const_iterator является зависимым, перед ним должно стоять ключевое слово >typename. Некоторые компиляторы принимают код без >typename, но такой код не переносится на другие платформы.

Надеюсь, вы обратили внимание на жирный шрифт в приведенных примерах. Выделение должно привлечь ваше внимание к особенно важным фрагментам кода. Нередко таким образом подчеркиваются различия между похожими примерами, как, например, при демонстрации двух разных способов объявления параметра Т в примере >Widget. Аналогичным образом помечаются и важные блоки на рисунках. Например, на диаграмме из совета 5 таким образом помечаются два указателя, изменяемые при вставке нового элемента в список.


В книге часто встречаются параметры >lhs и >rhs. Эти сокращения означают «left-hand side» («левая сторона») и «right-hand side» («правая сторона») соответственно, они особенно удобны при объявлении операторов. Пример из совета 19:

>class Widget {...}:

>bool operator==(const Widget& lhs. const Widgets rhs):

При вызове этой функции в контексте

>if (х==у) // Предполагается, что х и у

> // относятся к классу Widget

Объекту х, находящемуся слева от оператора =, в объявлении operator-= соответствует параметр Ihs, а объекту у соответствует параметр rhs.

Что касается имени класса Widget, то оно не имеет никакого отношения к графическим интерфейсам или инструментариям. Этим именем я привык обозначать «некий класс, который что-то делает». Иногда (как, например, на с. 20) имя Widget относится к шаблону класса, а не к классу. В таких случаях я продолжаю говорить о Widget как о классе несмотря на то, что в действительности это шаблон. Столь неформальное отношение к различиям между классами и шаблонами классов, структурами и шаблонами структур, функциями и шаблонами функций безвредно (при условии, что оно не приводит к возникновению неоднозначности в рассматриваемой теме). Если возможны какие-либо недоразумения, я провожу четкие различия между шаблонами и сгенерированными на их основе классами, структурами и функциями.