アン C++のイテレータ STL コンテナの要素を指すポインタのようなオブジェクトです。これらは通常、C++ で STL コンテナの内容をループするために使用されます。 STL イテレータの主な利点は、STL アルゴリズムが使用されるコンテナの種類に依存しないことです。コンテナ自体を STL アルゴリズムに渡すのではなく、イテレータをコンテナ要素に渡すだけです。
反復子の宣言
C++ STL の各コンテナには独自のイテレータがあります。したがって、イテレータを次のように宣言する必要があります。
C++
<type>::iterator it;
どこ
- タイプ: イテレータが宣言されているコンテナのタイプ。
- それ: イテレータオブジェクトに割り当てられた名前。
次に、有効なイテレータを割り当てて初期化できます。デカレーション時に割り当てられるイテレータがすでにある場合は、次のコマンドを使用して型宣言をスキップできます。 自動 キーワード。
C++auto it = iter
どこ イター 新しく作成された it イテレータに割り当てられるイテレータです。
私たちの C++コース STL でのイテレータの使用について説明しており、さまざまなコンテナ タイプを横断する方法を確実に理解できます。
イテレータの例
以下のプログラムは、反復子を使用してベクター コンテナーを走査する方法を示しています。
C++#include using namespace std; int main() { vector<int> v = {1 2 3 4 5}; // Defining an iterator pointing to // the beginning of the vector vector<int>::iterator first = v.begin(); // Defining an iterator pointing // to the end of the vector vector<int>::iterator last = v.end(); // Iterating the whole vector while(first != last) { cout << *first << ' '; first++; } return 0; }
出力
1 2 3 4 5
お気づきかと思いますが、私たちが使用したのは Vector::begin() と Vector::end() 関数。これらの関数は、ベクトルの最初の要素と最後の要素の 1 つ後の要素に反復子を返す std::vector のメンバー関数です。これらの関数のイテレータ return を使用して、ベクトルを反復します。
コンテナイテレータ関数
C++ STL では、いくつかのメンバー関数が提供されています。 STLコンテナ 反復子を少なくとも最初と最後の要素に返します。これらのメンバー関数は、ほぼすべての STL コンテナーで定義されます (ただし、次のようなアクセスが制限されたコンテナーは残ります)。 スタック 列 ) 一貫性を保つために同じ名前を付けます。
次の表に、コンテナにイテレータを返すすべてのメソッドを示します。
イテレータ関数 | 戻り値 |
|---|---|
始める() | イテレータをコンテナの先頭に返します。 |
終わり() | コンテナの最後の要素の直後にある理論上の要素に反復子を返します。 |
cbegin() | 定数イテレータをコンテナの先頭に返します。定数反復子は、それが指している要素の値を変更できません。 |
いくつか() 辞書初期化子C# | コンテナの最後の要素の直後にある理論上の要素に定数反復子を返します。 |
rbegin() | 逆反復子をコンテナの先頭に返します。 |
与える() | コンテナーの最後の要素の直後にある理論上の要素への逆反復子を返します。 |
crbegin() | 定数の逆反復子をコンテナーの先頭に返します。 |
クレンド () | コンテナーの最後の要素の直後にある理論上の要素に定数逆反復子を返します。 |
たとえば、 物 がベクトルの名前である場合、以下に示すように上記のメソッドを使用できます。
C++vec.begin() vec.rbegin() vec.cbegin() vec.crbegin() vec.end() vec.rend() vec.cend() vec.crend()
イテレータの操作
ポインター算術と同様に、C++ イテレーターで許可される演算がいくつかあります。これらはイテレータの重要性を高めるさまざまな機能を提供するために使用されます。有効なものは5つあります C++ でのイテレータ操作 :
- イテレータの逆参照
- 反復子のインクリメント/デクリメント
- イテレータへの整数の加算/減算
- 別のイテレータの減算
- イテレータの比較
イテレータの逆参照
逆参照操作により、ユーザーは次のことが可能になります。 アクセスまたは更新 イテレータが指す要素の値。私たちが使用するのは、 (*) 間接演算子 ポインタと同じように反復子を逆参照します。
C++// Access *it; // Update *it = new_val;
どこ 新しい値 イテレータが指す要素に割り当てられる新しい値です。 それ 。
反復子のインクリメント/デクリメント
次を使用してイテレータを 1 ずつインクリメントまたはデクリメントできます。 (++) または (--) 演算子 それぞれ。インクリメント操作ではイテレータがコンテナ内の次の要素に移動し、デクリメント操作ではイテレータが前の要素に移動します。
C++it++; // post-increment ++it; // pre-increment it--; // post-decrement --it; // pre-decrement
イテレータへの整数の加算/減算
イテレータに整数値を加算または減算することもできます。追加された整数値に応じて、次または前の位置に反復子が追加されます。
C++// Addition it + int_val; // Subtraction it - int_val;
どこ int_val イテレータに加算または減算される整数値です。 それ 。
別のイテレータの減算
ある反復子を別の反復子から減算して、それらが指しているメモリ間の距離 (または要素の数) を見つけることができます。
C++it1 - it2
イテレータの比較
同じ型の 2 つの反復子を相互にテストして、それらの間の関係を見つけることもできます。 (==) 等価演算子や (!=) 不等号演算子のような関係演算子を、次のような他の関係演算子と一緒に使用できます。< > <= >=。
C++it1 != it2 // Equal to it1 == it2 // Not equal to it1 > it2 // Greater than it1 < it2 // Less than it1 >= it2 // Greater than equal to it1 <= it2 // Less than equal to
C++ のイテレータの種類
STL イテレータは、実行できる操作に基づいて分割できます。 C++ には主に 5 つのタイプのイテレータがあり、サポートされているコンテナおよびサポートされているイテレータ操作とともに以下の表にリストされています。
イテレータ | 説明 | サポートされているコンテナ | サポートされている操作 |
|---|---|---|---|
入力反復子 | これは、値を読み取るために使用される一方向の反復子です。 | 入力ストリーム | 逆参照インクリメントの等価性 |
出力反復子 | これも一方向イテレータですが、値を割り当てるために使用されます。値にアクセスできません。 | 出力ストリーム | 逆参照 (書き込みのみ) 増分 |
前方反復子 | 値にアクセスしたり、値を割り当てたりすることができます。これは、入力反復子と出力反復子の両方を組み合わせたものです。 | forward_list unowned_map unowned_set | 逆参照インクリメントの等価性 |
双方向反復子 | 前方または後方の両方向に移動できます。リスト セットやマルチマップなどのコンテナーは、双方向イテレーターをサポートします。 | リスト マップ セット マルチマップ マルチセット | 逆参照インクリメント/デクリメントの等価性 |
ランダムアクセス反復子 | ランダム アクセス イテレータは、ポインタと同じ機能を提供する、ポイント先の要素から離れた要素にアクセスするために使用できるイテレータです。 | ベクトル両端子配列文字列 vlcでYouTubeビデオをダウンロード | 全て |
上の表からお気づきかと思いますが、入力反復子と出力反復子は別です。 表を下に進むにつれて、イテレータ型には上記のイテレータの機能といくつかの新しい機能が含まれています。
イテレータアダプタ
C++ のイテレータ アダプタは、特殊な機能を提供するために従来のイテレータ上に構築された特別なタイプのイテレータです。 C++ には多数の反復子アダプターがあり、その一部を以下に示します。
イテレータアダプタのタイプ | 説明 |
|---|---|
逆反復子 | 逆反復子は双方向以上のタイプの演算子上に構築されており、ユーザーがコンテナーを逆方向に走査できるようにします。 |
ストリーム反復子 | ストリーム反復子、つまり istream 反復子と ostream 反復子は、それぞれ入力反復子と出力反復子に基づいて構築されます。これらの反復子を使用すると、ユーザーはストリームをコンテナとして使用できます。 |
イテレータの移動 | 移動イテレータは、STL アルゴリズムに移動セマンティクスを導入するために使用されます。移動イテレーターは、追加のコピーを作成せずに、コピーされたコンテナー データの所有権をコピーするコンテナーに移動します。 |
インサーター反復子 | インサーター反復子を使用すると、コンテナー内の任意の位置に指定された要素を挿入できます。 C++ には 3 つの挿入反復子があります。
これらのイテレータは次を使用して作成できます。 back_inserter() フロントインサーター() 入れる() C++ の関数。 |
C++ の反復子ユーティリティ関数
C++ STL は、イテレータの操作を簡素化するさまざまな関数を提供します。以下の表にそれらを示します。
| 関数 | 説明 | 構文 |
|---|---|---|
| std::アドバンス | 反復子を特定の位置数だけ進めます。 | 前進 ( それは ) |
| std::next | 指定された反復子より指定された位置数だけ前にある反復子を返します。 | 次 ( それは ) |
| 標準 :: 前へ | 指定されたイテレータから指定された位置数だけ後ろにあるイテレータを返します。 | 前へ ( それは ) |
| 標準::距離 | 2 つのイテレータ間の要素の数を返します。 | 距離 ( それ1 それ2 ) |
| std::begin | 指定されたコンテナの最初の要素へのイテレータを返します。 | 始める ( 容器 ) |
| std::end | 指定されたコンテナの最後の要素に続く要素へのイテレータを返します。 | 終わり ( 容器 ) |
| std::rbegin | 指定されたコンテナの最後の要素への逆反復子を返します。 | 始める ( 容器 ) |
| std::レンド | 指定されたコンテナの最初の要素に先行する要素への逆反復子を返します。 | 作る ( 容器 ) |
| std::インサーター | コンテナーの指定された位置に要素を挿入する挿入イテレーターを作成します。 | インサータ ( コンテナの位置 ) |
| std::back_inserter | コンテナの末尾に要素を追加する後方挿入イテレータを作成します。 | バックインサーター ( 容器 ) |
| std::front_inserter | コンテナーの前面に要素を挿入する前面挿入イテレータを作成します。 | フロントインサーター ( 容器 ) |
イテレータの応用例と例
イテレーターは、STL コンテナーやアルゴリズムを操作する際に、C++ でさまざまな目的で広く使用されています。以下に、C++ でのイテレータの主なアプリケーションのコード例をいくつか示します。
コンテナの移動
STL コンテナの走査は、イテレータの最も基本的なアプリケーションです。ここでは begin() 関数と end() 関数を使用して、コンテナ全体を走査するための begin 反復子と end 反復子を取得します。基本的に、開始イテレータが終了と等しくなるまでインクリメントし続けます。
例
C++#include using namespace std; int main() { set<int> s = {10 20 30 40 50}; // Iterator to the beginning // of the set auto it = s.begin(); // Iterating through the // entire set while (it != s.end()) { // Dereferencing iterator // to access value cout << *it << ' '; // Incrementing the // iterator it++; } return 0; }
出力
10 20 30 40 50
上記のコードに示されているように、セット コンテナーをトラバースします。同様に、同じアプローチを使用して任意のコンテナを走査できます。
コンテナを反転する
逆反復子を使用すると、手動で反転を処理することなく、コンテナーを最後から最初までたどることができます。
例
C++#include using namespace std; int main() { vector<int> vec = {10 20 30 40 50}; // Defining reverse iterators // pointing to the reverse // beginning of vec auto it = vec.rbegin(); // Iterating the whole // vector in reverse while (it != vec.rend()) { cout << *it << ' '; it++; } return 0; }
出力
50 40 30 20 10
コンテナに依存しないアルゴリズム
イテレーターを使用すると、アルゴリズムが任意のコンテナー タイプで動作できるようになり、 std::sort() std::find() や std::for_each() などの関数がより柔軟になります。実際のコンテナの代わりにイテレータを渡すことができます。
例
C++#include using namespace std; int main() { vector<int> vec = {30 10 40 10 50}; multiset<int> ms = {10 30 10 20 40 10}; // Using the std::count() algorithm to count // the number of occurences of 10 in vector // and multiset using iterator cout << '10s in Vector: ' << count(vec.begin() vec.end() 10) << endl; cout << '10s in Multiset: ' << count(ms.begin() ms.end() 10); return 0; }
出力
10s in Vector: 2 10s in Multiset: 3
イテレータの追加のアプリケーション
STL イテレータの応用例は他にもあります。
- 距離の計算: std:: distance() イテレータを使用すると、コンテナ内の 2 つの位置間の要素の数を計算するのに役立ちます。
- ストリームの反復: ストリーム反復子を使用すると、入出力ストリームをコンテナのように扱うことができるため、STL アルゴリズムを使用したストリームの読み取りと書き込みが容易になります。
- STL アルゴリズムの移動セマンティクス: 移動イテレータは、STL アルゴリズムに移動セマンティクスを導入し、不必要なコピーを回避することでパフォーマンスと効率の向上に役立ちます。データは移動セマンティクスのルールに従って移動されます。
- データ構造のカスタム反復子: カスタム反復子をツリーやグラフなどの非 STL データ構造に実装して、STL アルゴリズムやその他の多くの機能のサポートを提供できます。適切なインクリメント、デクリメント、およびその他の操作を提供するには、いくつかのルールと規則に従う必要がある場合があります。