РУКОВОДСТВО ПО СТАНДАРТНОЙ БИБЛИОТЕКЕ ШАБЛОНОВ (STL)
Шрифт:
выражение | возвращаемый тип | семантика исполнения | утверждение/примечание состояние до/после |
---|---|---|---|
r += n | X& | {Distance m = n; if(m ›= 0) while(m--) ++r; else while(m++) --r; return r;} | – |
a + n n + a | X | {X tmp = a; return tmp += n;} | a + n == n + a. |
r -= n | X& | return r += -n; | – |
a - n | X | {X tmp = a; return tmp -= n;} | – |
b - a | Distance | – | до:
|
a[n] | обратимый в T | *(a + n) | – |
a ‹ b | обратимый в bool | b - a › 0 | ‹ - это отношение полного упорядочения |
a › b | обратимый в bool | b ‹ a | › - это отношение полного упорядочения, противоположное ‹. |
a ›= b | обратимый в bool | !(a ‹ b) | – |
a ‹= b | обратимый в bool | !(a › b) | – |
Теги итераторов (Iterator tags)
Чтобы осуществлять алгоритмы только в терминах итераторов, часто бывает необходимо вывести тип значения и тип расстояния из итератора. Для решения этой задачи требуется, чтобы для итератора i любой категории, отличной от итератора вывода, выражение value_type(i) возвращало (T*)(0), а выражение distance_type(i) возвращало (Distance*)(0). Для итераторов вывода эти выражения не требуются.
Примеры использования тегов итераторов
Для всех типов обычных указателей мы можем определить value_type и distance_type с помощью следующего:
Тогда, если мы хотим осуществить обобщённую функцию reverse, мы пишем следующее:
где _reverse определена следующим образом:
Если
Часто желательно для шаблонной функции выяснить, какова наиболее специфичная категория её итераторного аргумента, так чтобы функция могла выбирать наиболее эффективный алгоритм во время компиляции. Чтобы облегчить это, библиотека вводит классы тегов категорий (category tag), которые используются как теги времени компиляции для выбора алгоритма. Это следущие теги: input_iterator_tag, output_iterator_tag, forward_iterator_tag, bidirectional_iterator_tag и random_access_iterator_tag. Каждый итератор i должен иметь выражение iterator_category(i), определённое для него, которое возвращает тег наиболее специфичной категории, который описывает его поведение. Например, мы определяем, что все типы указателей находятся в категории итераторов произвольного доступа:
Определяемый пользователем итератор BinaryTreeIterator может быть включен в категорию двунаправленных итераторов следующим образом:
Если шаблонная функция evolve хорошо определена для двунаправленных итераторов, но может быть осуществлена более эффективно для итераторов произвольного доступа, тогда реализация выглядит так:
Примитивы, определённые в библиотеке
Чтобы упростить задачу определения iterator_category, value_type и distance_type для определяемых пользователем итераторов, библиотека обеспечивает следующие предопределённые классы и функции: