std::iterator_traits

来自cppreference.com
< cpp‎ | iterator
 
 
迭代器库
迭代器概念
迭代器原语
(C++17 中弃用)
iterator_traits


算法概念与工具
间接可调用概念
常用算法要求
(C++20)
(C++20)
(C++20)
工具
(C++20)
迭代器适配器
范围访问
(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) 类型各项属性的统一接口。这使得可以仅通过迭代器实现算法。

可针对用户定义的迭代器特化此模板,使得即使不提供通常的 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 缺少以上五个嵌套类型之一,那么此模板不会包含任何有这些名称的成员(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* 的两种偏特化,使得可以在任何需要迭代器的算法里使用裸指针。

标准库也会提供对一些标准迭代器适配器的特化。

(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::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); // 编译错误:il, i2 是输入迭代器
}

输出:

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

参阅

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