名前空間
変種
操作

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_traitsLegacyIterator 型の性質への統一されたインタフェースを提供する型特性クラスです��� これによりアルゴリズムをイテレータの観点のみで実装することが可能となります。

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

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

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

(C++17以上)
(C++20未満)

Iterpointer を持たないけれども他の4つのメンバ型をすべて持つ場合、メンバ型は以下のように宣言されます。

メンバ型 定義
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::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-friendly です)。

(C++20以上)

[編集] 特殊化

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

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

std::is_object_v<T> が真の場合にのみ特殊化されます。

(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未満)

[編集]

以下の例は双方向イテレータに対する汎用の 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で非推奨)
シンプルなイテレータのための型要件の定義を簡単にする基底クラス
(クラステンプレート) [edit]
イテレータのカテゴリを表すために使用される空のクラス型
(クラス) [edit]