std::iterator_traits
<iterator>
struct iterator_traits;
struct iterator_traits<T*>;
struct iterator_traits<const T*>;
std::iterator_traits
is the type trait class that provides uniform interface to the properties of LegacyIterator types. This makes it possible to implement algorithms only in terms of iterators.
The template can be specialized for user-defined iterators so that the information about the iterator can be retrieved even if the type does not provide the usual typedefs.
User specializations may define the nested type iterator_concept
to one of iterator category tags, to indicate conformance to the iterator concepts.
Contents
[edit] Template parameters
[edit] Member types
difference_type
Iter::difference_type
value_type
Iter::value_type
pointer
Iter::pointer
reference
Iter::reference
iterator_category
Iter::iterator_category
If Iter
does not have any of the five nested types above, then this template has no members by any of those names (std::iterator_traits
is SFINAE-friendly).
(until C++20)
If Iter
does not have pointer
, but has all four remaining nested types, then these four nested types are declared as follows:
difference_type
Iter::difference_type
value_type
Iter::value_type
pointer
void
reference
Iter::reference
iterator_category
Iter::iterator_category
Otherwise, if Iter
satisfies the exposition-only concept __LegacyInputIterator, the nested types are declared as follows:
difference_type
std::incrementable_traits <Iter>::difference_type
value_type
std::indirectly_readable_traits <Iter>::value_type
pointer
-
Iter::pointer
if valid. - Otherwise decltype(std::declval <Iter&>().operator->()) if valid.
- Otherwise void.
reference
-
Iter::reference
if valid. - Otherwise std::iter_reference_t <Iter>.
iterator_category
-
Iter::iterator_category
if valid. - Otherwise, std::random_access_iterator_tag if
Iter
satisfies __LegacyRandomAccessIterator. - Otherwise, std::bidirectional_iterator_tag if
Iter
satisfies __LegacyBidirectionalIterator. - Otherwise, std::forward_iterator_tag if
Iter
satisfies __LegacyForwardIterator. - Otherwise, std::input_iterator_tag .
Otherwise, if Iter
satisfies the exposition-only concept __LegacyIterator, the nested types are declared as follows:
difference_type
- std::incrementable_traits <Iter>::difference_type if valid.
- Otherwise void.
value_type
void
pointer
void
reference
void
iterator_category
std::output_iterator_tag
Otherwise, this template has no members by any of those names (std::iterator_traits
is SFINAE-friendly).
[edit] Specializations
This type trait may be specialized for user-provided types that may be used as iterators. The standard library provides partial specializations for pointer types T*
, which makes it possible to use all iterator-based algorithms with raw pointers.
The standard library also provides partial specializations for some standard iterator adaptors.
(since C++20)
[edit] T*
specialization nested types
Only specialized if std::is_object_v <T> is true.
(since C++20)
difference_type
std::ptrdiff_t
pointer
T*
reference
T&
iterator_category
std::random_access_iterator_tag
const T* specialization nested types
difference_type
std::ptrdiff_t
value_type
T
pointer
const T*
reference
const T&
iterator_category
std::random_access_iterator_tag
[edit] Specializations for library types
(class template specialization) [edit]
(class template specialization) [edit]
[edit] Example
Shows a general-purpose std::reverse () implementation for bidirectional iterators.
#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 }
Output:
5 4 3 2 1 5 4 3 2 1 5 4 3 2 1
[edit] See also
(class template) [edit]
(alias template)[edit]