std::iterator_traits
Объявлен в заголовочном файле <iterator> | ||
|---|---|---|
template< class Iter > struct iterator_traits; | ||
template< class T > struct iterator_traits<T*>; | ||
template< class T > struct iterator_traits<const T*>; | (удалено в C++20) |
std::iterator_traits — это класс признака типа, предоставляющий унифицированный интерфейс к свойствам типов LegacyIterator. Это позволяет реализовывать алгоритмы, используя только итераторы.
Шаблон можно специализировать для пользовательских итераторов, чтобы можно было получить информацию об итераторе, даже если тип не предоставляет обычные определения типов.
| Пользовательские специализации могут определять вложенный тип | (начиная с C++20) |
Параметры шаблона
| Iter | - | тип итератора, свойства которого нужно получить |
Типы-члены
| Вложенный тип | Определение |
|---|---|
difference_type |
Iter::difference_type |
value_type |
Iter::value_type |
pointer |
Iter::pointer |
reference |
Iter::reference |
iterator_category |
Iter::iterator_category |
| Если |
(начиная с C++17) (до C++20 включительно) |
||||||||||||||||||||||||||||||||||||
| Если
В противном случае этот шаблон не имеет членов с такими именами ( | (начиная с C++20) |
Специализации
Этот признак типа можно специализировать для пользовательских типов, которые могут использоваться в качестве итераторов. Стандартная библиотека предоставляет частичные специализации для типов-указателей T*, что позволяет использовать все алгоритмы, основанные на итераторах, с обычными указателями.
| Стандартная библиотека также предоставляет частичные специализации для некоторых стандартных адаптеров итераторов. | (начиная с C++20) |
Вложенные типы специализации T*
| Специализация существует только в том случае, если | (начиная с C++20) |
| Вложенный тип | Определение |
|---|---|
difference_type |
std::ptrdiff_t |
value_type |
T(до C++20 включительно)std::remove_cv_t<T>(начиная с C++20) |
pointer |
T* |
reference |
T& |
iterator_category |
std::random_access_iterator_tag |
iterator_concept (начиная с C++20) |
std::contiguous_iterator_tag |
Вложенные типы специализации constT*
| (до C++20 включительно) |
Специализации для типов библиотеки
|
(C++20) | предоставляет унифицированный интерфейс к свойствам типа std::common_iterator (специализация шаблона класса) |
|
(C++20) | предоставляет унифицированный интерфейс к свойствам типа std::counted_iterator (специализация шаблона класса) |
Пример
Показывает реализацию std::reverse() общего назначения для двунаправленных итераторов.
#include <iostream>
#include <iterator>
#include <list>
#include <vector>
template<class BidirIt>
void my_reverse(BidirIt first, BidirIt last)
{
typename std::iterator_traits<BidirIt>::difference_type n = std::distance(first, last);
for (--n; n > 0; n -= 2)
{
typename std::iterator_traits<BidirIt>::value_type tmp = *first;
*first++ = *--last;
*last = tmp;
}
}
int main()
{
std::vector<int> v{1, 2, 3, 4, 5};
my_reverse(v.begin(), v.end());
for (int n : v)
std::cout << n << ' ';
std::cout << '\n';
std::list<int> l{1, 2, 3, 4, 5};
my_reverse(l.begin(), l.end());
for (int n : l)
std::cout << n << ' ';
std::cout << '\n';
int a[]{1, 2, 3, 4, 5};
my_reverse(a, a + std::size(a));
for (int n : a)
std::cout << n << ' ';
std::cout << '\n';
// std::istreambuf_iterator<char> i1(std::cin), i2;
// my_reverse(i1, i2); // compilation error: i1, i2 are input iterators
}
Вывод:
5 4 3 2 1 5 4 3 2 1 5 4 3 2 1
См. также
|
(устарело в C++17) | базовый класс, упрощающий определение необходимых типов для простых итераторов (шаблон класса) |
|
(C++20) | пустые типы классов, обозначающие категории итераторов (класс) |
|
(C++20)(C++20)(C++23)(C++20)(C++20)(C++20) | вычисляет связанные типы итератора (шаблон псевдонима) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/iterator/iterator_traits