Spec-Zone.ru › C++

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. Это позволяет реализовывать алгоритмы, используя только итераторы.

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

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

(начиная с 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
  • Iter::reference, если допустимо.
  • В противном случае std::iter_reference_t<Iter>.
iterator_category
  • Iter::iterator_category, если допустимо.
  • В противном случае, std::random_access_iterator_tag, если Iter удовлетворяет __LegacyRandomAccessIterator.
  • В противном случае, std::bidirectional_iterator_tag, если Iter удовлетворяет __LegacyBidirectionalIterator.
  • В противном случае, std::forward_iterator_tag, если Iter удовлетворяет __LegacyForwardIterator.
  • В противном случае, std::input_iterator_tag.


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

Вложенный тип Определение
difference_type
  • std::incrementable_traits<Iter>::difference_type, если допустимо.
  • В противном случае void.
value_type void
pointer void
reference void
iterator_category std::output_iterator_tag

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

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

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

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

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

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

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

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

(начиная с 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*

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

Специализации для типов библиотеки

std::iterator_traits<std::common_iterator>
(C++20)
предоставляет унифицированный интерфейс к свойствам типа std::common_iterator
(специализация шаблона класса)
std::iterator_traits<std::counted_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

См. также

iterator
(устарело в C++17)
базовый класс, упрощающий определение необходимых типов для простых итераторов
(шаблон класса)
input_iterator_tagoutput_iterator_tagforward_iterator_tagbidirectional_iterator_tagrandom_access_iterator_tagcontiguous_iterator_tag
(C++20)
пустые типы классов, обозначающие категории итераторов
(класс)
iter_value_titer_reference_titer_const_reference_titer_difference_titer_rvalue_reference_titer_common_reference_t
(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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API