std:: input_iterator_tag, std:: output_iterator_tag, std:: forward_iterator_tag, std:: bidirectional_iterator_tag, std:: random_access_iterator_tag, std:: contiguous_iterator_tag
|
Определено в заголовочном файле
<iterator>
|
||
|
struct
input_iterator_tag
{
}
;
|
(1) | |
|
struct
output_iterator_tag
{
}
;
|
(2) | |
|
struct
forward_iterator_tag
:
public
input_iterator_tag
{
}
;
|
(3) | |
|
struct
bidirectional_iterator_tag
:
public
forward_iterator_tag
{
}
;
|
(4) | |
|
struct
random_access_iterator_tag
:
public
bidirectional_iterator_tag
{
}
;
|
(5) | |
|
struct
contiguous_iterator_tag
:
public
random_access_iterator_tag
{
}
;
|
(6) | (начиная с C++20) |
Определяет категорию итератора. Каждый тег является пустым типом.
Содержание |
Категория итератора
Для каждого
LegacyIterator
типа
It
, должен быть определён
typedef
std::
iterator_traits
<
It
>
::
iterator_category
как псевдоним одного из этих типов-меток, чтобы указать наиболее специфичную категорию, к которой принадлежит
It
.
-
input_iterator_tagсоответствует LegacyInputIterator . -
output_iterator_tagсоответствует LegacyOutputIterator . -
forward_iterator_tagсоответствует LegacyForwardIterator . -
bidirectional_iterator_tagсоответствует LegacyBidirectionalIterator . -
random_access_iterator_tagсоответствует LegacyRandomAccessIterator .
Теги категорий итераторов содержат информацию, которая может быть использована для выбора наиболее эффективных алгоритмов под конкретный набор требований, подразумеваемый категорией.
Концепция итератора
Для каждого типа
Если
В любом случае, каждая концепция не удовлетворяется, если требуемые операции не поддерживаются, независимо от тега. |
(начиная с C++20) |
Примечания
Отдельного тега для
LegacyContiguousIterator
не существует. То есть, невозможно определить
LegacyContiguousIterator
на основе его
iterator_category
.
Для определения специализированных алгоритмов для непрерывных итераторов используйте
contiguous_iterator
концепт.
(начиная с C++20)
Не существует соответствий между
output_iterator_tag
и концепцией
output_iterator
. Установка
iterator_concept
в
output_iterator_tag
только указывает, что тип не моделирует
input_iterator
.
Пример
Распространённой техникой для выбора алгоритма на основе тегов категорий итераторов является использование диспетчерской функции (альтернативой является std::enable_if ). Классы тегов итераторов также используются в соответствующих определениях концепций для обозначения требований, которые не могут быть выражены только через шаблоны использования. (начиная с C++20)
#include <iostream> #include <iterator> #include <list> #include <vector> // Using concepts (tag checking is part of the concepts themselves) template<std::bidirectional_iterator BDIter> void alg(BDIter, BDIter) { std::cout << "1. alg() \t called for bidirectional iterator\n"; } template<std::random_access_iterator RAIter> void alg(RAIter, RAIter) { std::cout << "2. alg() \t called for random-access iterator\n"; } // Legacy, using tag dispatch namespace legacy { // Quite often implementation details are hidden in a dedicated namespace namespace implementation_details { template<class BDIter> void alg(BDIter, BDIter, std::bidirectional_iterator_tag) { std::cout << "3. legacy::alg() called for bidirectional iterator\n"; } template<class RAIter> void alg(RAIter, RAIter, std::random_access_iterator_tag) { std::cout << "4. legacy::alg() called for random-access iterator\n"; } } // namespace implementation_details template<class Iter> void alg(Iter first, Iter last) { implementation_details::alg(first, last, typename std::iterator_traits<Iter>::iterator_category()); } } // namespace legacy int main() { std::list<int> l; alg(l.begin(), l.end()); // 1. legacy::alg(l.begin(), l.end()); // 3. std::vector<int> v; alg(v.begin(), v.end()); // 2. legacy::alg(v.begin(), v.end()); // 4. // std::istreambuf_iterator<char> i1(std::cin), i2; // alg(i1, i2); // compile error: no matching function for call // legacy::alg(i1, i2); // compile error: no matching function for call }
Вывод:
1. alg() called for bidirectional iterator 3. legacy::alg() called for bidirectional iterator 2. alg() called for random-access iterator 4. legacy::alg() called for random-access iterator
Смотрите также
|
(deprecated in C++17)
|
базовый класс для упрощения определения требуемых типов для простых итераторов
(class template) |
|
предоставляет унифицированный интерфейс к свойствам итератора
(class template) |