std::iterator_traits
| ヘッダ <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 型の性質への統一されたインタフェースを提供する型特性クラスです。 これによりアルゴリズムをイテレータの観点のみで実装することが可能となります。
このクラスは以下の型を定義します。
difference_type- イテレータ間の距離を表すために使用できる符号付き整数型。value_type- イテレータを逆参照することによって取得できる値の型。 この型は出力イテレータに対してはvoidになります。pointer- イテレートする型 (value_type) を指すポインタを定義します。reference- イテレートする型 (value_type) を指す参照を定義します。iterator_category- イテレータのカテゴリ。 イテレータカテゴリタグのいずれかでなければなりません。
このテンプレートは、その型が通常の typedef を提供しなくてもイテレータに関する情報を取得できるように、ユーザ定義のイテレータに対して特殊化しても構いません。
|
ユーザの特殊化は、イテレータコンセプトへの準拠を示すために、メンバ型 |
(C++20以上) |
テンプレート引数
| Iter | - | 性質を取得するイテレータ型 |
メンバ型
| メンバ型 | 定義 |
difference_type
|
Iter::difference_type
|
value_type
|
Iter::value_type
|
pointer
|
Iter::pointer
|
reference
|
Iter::reference
|
iterator_category
|
Iter::iterator_category
|
|
|
(C++17以上) (C++20未満) | ||||||||||||||||||||||||||||||||||||
|
そうでなく、
そうでなく、
そうでなければ、このテンプレートはこれらの名前のいずれのメンバも持ちません ( |
(C++20以上) |
特殊化
この型特性はイテレータとして使用できるユーザ提供の型に対して特殊化しても構いません。 標準ライブラリはポインタ型 T* に対する2つの部分特殊化を提供しています。 これによりすべてのイテレータベースのアルゴリズムを生のポインタで使用することが可能となります。
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 |
|
| メンバ型 | 定義 |
difference_type
|
std::ptrdiff_t |
value_type
|
T
|
pointer
|
const T*
|
reference
|
const T&
|
iterator_category
|
std::random_access_iterator_tag |
例
以下の例は双方向イテレータに対する汎用の 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で非推奨) |
シンプルなイテレータのための型要件の定義を簡単にする基底クラス (クラステンプレート) |
| イテレータのカテゴリを表すために使用される空のクラス型 (クラス) |