std::iterator_traits

来自cppreference.com
< cpp‎ | iterator
 
 
迭代器库
迭代器概念
迭代器原语
算法概念与工具
间接可调用概念
常用算法要求
工具
迭代器适配器
流迭代器
迭代器定制点
迭代器操作
(C++11)
(C++11)
范围访问
(C++11)(C++14)
(C++11)(C++14)
(C++17)(C++20)
(C++14)(C++14)
(C++14)(C++14)
(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) 类型的统一接口。这使得可以仅通过迭代器实现算法。

能对用户定义的迭代器特化模板,使得即使不提供通常的 typedef 也能从迭代器取得信息。

用户定义特化可以定义成员类型 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 没有全部五个成员类型 difference_typevalue_typepointerreferenceiterator_category ,则此模板无任何有那些名称的成员( std::iterator_traits 对 SFINAE 友好)

(C++17 起)
(C++20 前)

Iterpointer ,但拥有全部其他四个成员类型,则按如下方式声明成员类型:

成员类型 定义
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
否则若 Iter 满足 __LegacyRandomAccessIterator

则为 std::random_access_iterator_tag
否则若 Iter 满足 __LegacyBidirectionalIterator 则为 std::bidirectional_iterator_tag
否则若 Iter 满足 __LegacyForwardIterator 则为 std::forward_iterator_tag
否则为 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

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::counted_iterator 类型的属性提供均一的接口
(类模板特化)
std::counted_iterator 类型的属性提供均一的接口
(类模板特化)

示例

下列使用展示对双向迭代器的通用 reverse() 实现

#include <iostream>
#include <iterator>
#include <vector>
#include <list>
 
template<class BidirIt>
void my_reverse(BidirIt first, BidirIt last)
{
    typename std::iterator_traits<BidirIt>::difference_type n = std::distance(first, last);
    --n;
    while(n > 0) {
        typename std::iterator_traits<BidirIt>::value_type tmp = *first;
        *first++ = *--last;
        *last = tmp;
        n -= 2;
    }
}
 
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 (auto n : l) {
        std::cout << n << ' ';
    }
    std::cout << '\n';
 
    int a[] = {1, 2, 3, 4, 5};
    my_reverse(a, a+5);
    for (int i=0; i<5; ++i) {
        std::cout << a[i] << ' ';
    }
    std::cout << '\n';
 
//    std::istreambuf_iterator<char> i1(std::cin), i2;
//    my_reverse(i1, i2); // 编译错误
 
}

输出:

5 4 3 2 1
5 4 3 2 1
5 4 3 2 1

参阅

(C++17 中弃用)
用于简化简单的迭代器的必要类型定义的基类
(类模板)
用于指示迭代器类别的空类类型
(类)