名前空間
変種
操作

std::iterator_traits

From cppreference.com
 
 
イテレータライブラリ
イテレータのコンセプト
イテレータのプリミティブ
(C++17で非推奨)
iterator_traits


アルゴリズムのコンセプトとユーティリティ
間接呼び出し可能コンセプト
共通アルゴリズム要件
(C++20)
(C++20)
(C++20)
ユーティリティ
(C++20)
イテレータアダプタ
Rangeアクセス
(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がいずれかの5つのネストされた型を持たない場合、このテンプレートはその名前のメンバを持ちません(std::iterator_traitsはSFINAEフレンドリーです)。

(C++17以降)
(C++20まで)

Iterpointerを持たず、残りの4つのネストされた型すべてを持つ場合、これらの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::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); // compilation error: i1, i2 are input iterators
}

出力

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

[編集] 関連項目

(C++17で非推奨)
単純なイテレータに必要な型の定義を容易にするための基底クラス
(クラステンプレート) [編集]
イテレータカテゴリを示すために使用される空のクラス型
(クラス) [編集]
イテレータの関連型を計算する
(エイリアステンプレート)[編集]
English 日本語 中文(简体) 中文(繁體)