Namespaces
Variants

std:: iterator_traits

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
(deprecated in C++17)
iterator_traits


Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
Определено в заголовочном файле <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 . Это позволяет реализовывать алгоритмы исключительно в терминах итераторов.

Шаблон может быть специализирован для пользовательских итераторов, чтобы информация об итераторе могла быть получена, даже если тип не предоставляет стандартные typedefs.

Пользовательские специализации могут определять вложенный тип iterator_concept как один из тегов категорий итераторов , чтобы указать соответствие концепциям итераторов.

(since C++20)

Содержание

Параметры шаблона

Iter - тип итератора для получения свойств

Типы членов

Вложенный тип Определение
difference_type Iter::difference_type
value_type Iter::value_type
pointer Iter::pointer
reference Iter::reference
iterator_category Iter::iterator_category


Если Iter не имеет ни одного из пяти вложенных типов выше, то этот шаблон не имеет членов с такими именами ( std::iterator_traits является SFINAE-дружественным).

(начиная с C++17)
(до C++20)

Если Iter не имеет pointer , но имеет все четыре оставшихся вложенных типа, то эти четыре вложенных типа объявляются следующим образом:

Вложенный тип Определение
difference_type Iter::difference_type
value_type Iter::value_type
pointer void
reference Iter::reference
iterator_category Iter::iterator_category


В противном случае, если Iter удовлетворяет экспозиционному концепту __LegacyInputIterator , вложенные типы объявляются следующим образом:

Вложенный тип Определение
difference_type std:: incrementable_traits < Iter > :: difference_type
value_type std:: indirectly_readable_traits < Iter > :: value_type
pointer
  • Iter::pointer если допустимо.
  • Иначе decltype ( std:: declval < Iter & > ( ) . operator - > ( ) ) если допустимо.
  • Иначе void .
reference
iterator_category


В противном случае, если Iter удовлетворяет экспозиционному концепту __LegacyIterator , вложенные типы объявляются следующим образом:

Вложенный тип Определение
difference_type
value_type void
pointer void
reference void
iterator_category std::output_iterator_tag

В противном случае, этот шаблон не имеет членов с такими именами ( std::iterator_traits является SFINAE-дружественным).

(начиная с C++20)

Специализации

Этот трейт типа может быть специализирован для пользовательских типов, которые могут использоваться в качестве итераторов. Стандартная библиотека предоставляет частичные специализации для указателей T* , что позволяет использовать все алгоритмы, основанные на итераторах, с сырыми указателями.

Стандартная библиотека также предоставляет частичные специализации для некоторых стандартных адаптеров итераторов.

(since C++20)

T* специализация вложенные типы

Специализируется только если std:: is_object_v < T > равно true .

(since 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


const T * вложенные типы специализации

Вложенный тип Определение
difference_type std::ptrdiff_t
value_type T
pointer const T *
reference const T &
iterator_category std::random_access_iterator_tag
(до C++20)

Специализации для библиотечных типов

предоставляет унифицированный интерфейс к свойствам типа std::common_iterator
(специализация шаблона класса)
предоставляет унифицированный интерфейс к свойствам типа 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)
базовый класс для упрощения определения требуемых типов для простых итераторов
(шаблон класса)
пустые типы классов, используемые для указания категорий итераторов
(класс)
вычисляет ассоциированные типы итератора
(псевдоним шаблона)