名前空間
変種
操作

std::iterator_traits

提供: cppreference.com
< cpp‎ | iterator
ヘッダ <iterator> で定義
template< class Iterator >
struct iterator_traits;
template< class T >
struct iterator_traits<T*>;
template< class T >
struct iterator_traits<const T*>;
(C++20以前)

std::iterator_traitsIterator 型の性質への統一されたインタフェースを提供する型特性クラスです。 これによりアルゴリズムをイテレータの観点のみで実装することが可能となります。

このクラスは以下の型を定義します。

  • difference_type - イテレータ間の距離を表すために使用できる符号付き整数型。
  • value_type - イテレータを逆参照することによって取得できる値の型。 この型は出力イテレータに対しては void になります。
  • pointer - イテレートする型 (value_type) を指すポインタを定義します。
  • reference - イテレートする型 (value_type) を指す参照を定義します。
  • iterator_category - イテレータのカテゴリ。 イテレータカテゴリタグのいずれかでなければなりません。

このテンプレートは、その型が通常の typedef を提供しなくてもイテレータに関する情報を取得できるように、ユーザ定義のイテレータに対して特殊化しても構いません。

目次

[編集] テンプレート引数

Iterator - 性質を取得するイテレータ型

[編集] メンバ型

メンバ型 定義
difference_type Iterator::difference_type
value_type Iterator::value_type
pointer Iterator::pointer
reference Iterator::reference
iterator_category Iterator::iterator_category

Iterator が5つのメンバ型 difference_typevalue_typepointerreference および iterator_category をすべて提供していない場合、このテンプレートはこれらの名前のいずれのメンバも持ちません (std::iterator_traits は SFINAE-friendly です)。

(C++17およびそれ以降)

[編集] 特殊化

この型特性はイテレータとして使用できるユーザ提供の型に対して特殊化しても構いません。 標準ライブラリはポインタ型 T* に対する2つの部分特殊化を提供しています。 これによりすべてのイテレータベースのアルゴリズムを生のポインタで使用することが可能となります。

[編集] T* 特殊化のメンバ型

メンバ型 定義
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

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以前)

[編集]

以下の例は双方向イテレータに対する汎用の 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); // compilation error
 
}

出力:

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

[編集] 関連項目

(C++17で非推奨)
シンプルなイテレータのための型要件の定義を簡単にする基底クラス
(クラステンプレート) [edit]
イテレータのカテゴリを示すために使用される空クラス型
(クラス) [edit]