Files
2025-10-25 03:02:53 +03:00

12 KiB
Raw Permalink Blame History

[iterator.traits]

24 Iterators library [iterators]

24.3 Iterator requirements [iterator.requirements]

24.3.2 Associated types [iterator.assoc.types]

24.3.2.3 Iterator traits [iterator.traits]

1

#

To implement algorithms only in terms of iterators, it is sometimes necessary to determine the iterator category that corresponds to a particular iterator type.

Accordingly, it is required that ifI is the type of an iterator, the type

🔗

iterator_traits::iterator_category be defined as the iterator's iterator category.

In addition, the types

🔗

iterator_traits::pointer iterator_traits::reference shall be defined as the iterator's pointer and reference types; that is, for an iterator object a of class type, the same type asdecltype(a.operator->()) anddecltype(*a), respectively.

The typeiterator_traits::pointer shall be void for an iterator of class type I that does not support operator->.

Additionally, in the case of an output iterator, the typesiterator_traits::value_type iterator_traits::difference_type iterator_traits::reference may be defined as void.

2

#

The definitions in this subclause make use of the following exposition-only concepts:templateconcept cpp17-iterator =requires(I i) {{ *i } -> can-reference; { ++i } -> same_as<I&>; { *i++ } -> can-reference; } && copyable;

templateconcept cpp17-input-iterator =cpp17-iterator && equality_comparable && requires(I i) {typename incrementable_traits::difference_type; typename indirectly_readable_traits::value_type; typename common_reference_t<iter_reference_t&&, typename indirectly_readable_traits::value_type&>; typename common_reference_t<decltype(*i++)&&, typename indirectly_readable_traits::value_type&>; requires signed_integral<typename incrementable_traits::difference_type>; };

templateconcept cpp17-forward-iterator =cpp17-input-iterator && constructible_from && is_reference_v<iter_reference_t> &&same_as<remove_cvref_t<iter_reference_t>, typename indirectly_readable_traits::value_type> &&requires(I i) {{ i++ } -> convertible_to<const I&>; { *i++ } -> same_as<iter_reference_t>; };

templateconcept cpp17-bidirectional-iterator =cpp17-forward-iterator && requires(I i) {{ --i } -> same_as<I&>; { i-- } -> convertible_to<const I&>; { *i-- } -> same_as<iter_reference_t>; };

templateconcept cpp17-random-access-iterator =cpp17-bidirectional-iterator && totally_ordered &&requires(I i, typename incrementable_traits::difference_type n) {{ i += n } -> same_as<I&>; { i -= n } -> same_as<I&>; { i + n } -> same_as; { n + i } -> same_as; { i - n } -> same_as; { i - i } -> same_as<decltype(n)>; { i[n] } -> convertible_to<iter_reference_t>; };

3

#

The members of a specialization iterator_traits generated from theiterator_traits primary template are computed as follows:

If I has valid ([temp.deduct]) member types difference_type, value_type,reference, and iterator_category, theniterator_traits has the following publicly accessible members:using iterator_category = typename I::iterator_category;using value_type = typename I::value_type;using difference_type = typename I::difference_type;using pointer = see below;using reference = typename I::reference; If the qualified-id I::pointer is valid and denotes a type, then iterator_traits::pointer names that type; otherwise, it names void.

Otherwise, if I satisfies the exposition-only conceptcpp17-input-iterator,iterator_traits has the following publicly accessible members:using iterator_category = see below;using value_type = typename indirectly_readable_traits::value_type;using difference_type = typename incrementable_traits::difference_type;using pointer = see below;using reference = see below;

  • (3.2.1)

    If the qualified-id I::pointer is valid and denotes a type,pointer names that type. Otherwise, ifdecltype(declval<I&>().operator->()) is well-formed, thenpointer names that type. Otherwise, pointer names void.

  • (3.2.2)

    If the qualified-id I::reference is valid and denotes a type, reference names that type. Otherwise, reference names iter_reference_t.

  • (3.2.3)

    If the qualified-id I::iterator_category is valid and denotes a type, iterator_category names that type. Otherwise, iterator_category names: + (3.2.3.1) random_access_iterator_tag ifI satisfies cpp17-random-access-iterator, or otherwise

    • [(3.2.3.2)](#3.2.3.2)
      

bidirectional_iterator_tag ifI satisfies cpp17-bidirectional-iterator, or otherwise

+
      [(3.2.3.3)](#3.2.3.3)

forward_iterator_tag ifI satisfies cpp17-forward-iterator, or otherwise

+
      [(3.2.3.4)](#3.2.3.4)

input_iterator_tag.

Otherwise, if I satisfies the exposition-only conceptcpp17-iterator, then iterator_traits has the following publicly accessible members:using iterator_category = output_iterator_tag;using value_type = void;using difference_type = see below;using pointer = void;using reference = void; If the qualified-idincrementable_traits::difference_type is valid and denotes a type, then difference_type names that type; otherwise, it names void.

Otherwise, iterator_traits has no members by any of the above names.

4

#

Explicit or partial specializations of iterator_traits may have a member type iterator_concept that is used to indicate conformance to the iterator concepts ([iterator.concepts]).

[Example 1:

To indicate conformance to the input_iterator concept but a lack of conformance to the Cpp17InputIterator requirements ([input.iterators]), an iterator_traits specialization might haveiterator_concept denote input_iterator_tag but not define iterator_category.

— end example]

5

#

iterator_traits is specialized for pointers asnamespace std {templaterequires is_object_vstruct iterator_traits<T*> {using iterator_concept = contiguous_iterator_tag; using iterator_category = random_access_iterator_tag; using value_type = remove_cv_t; using difference_type = ptrdiff_t; using pointer = T*; using reference = T&; };}

6

#

[Example 2:

To implement a genericreverse function, a C++ program can do the following:templatevoid reverse(BI first, BI last) {typename iterator_traits::difference_type n = distance(first, last); --n; while (n > 0) {typename iterator_traits::value_type tmp = *first; *first++ = *--last; *last = tmp; n -= 2; }}

— end example]