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
См. также
|
(устаревший в C++17) | базовый класс для облегчения определения требуемых типов для простых итераторов (шаблон класса) |
| обеспечивает единообразный интерфейс к свойствам итератора (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/iterator/iterator_tags