【C++】イテレータ入門 | コンテナの要素にアクセスする汎用的な方法

目次

はじめに

C++の標準ライブラリ(STL)の中心的な設計思想の一つが、「アルゴリズム」と「コンテナ」の分離です。std::sortstd::findといったアルゴリズムは、std::vectorstd::listといった特定のコンテナに依存しません。

この両者の架け橋となるのが「イテレータ (iterator)」です。イテレータは、コンテナ内の要素の位置を示す、汎用的なポインタのようなものです。アルゴリズムは、コンテナの種類を直接知らなくても、イテレータを通じて要素にアクセスし、様々な操作を行います。

この記事では、イテレータの基本的な概念と、それがいかにしてC++の柔軟性を高めているのかを、自作のfindアルゴリズムを例に解説します。


イテレータを使った汎用的な検索関数のサンプルコード

このコードは、任意のコンテナ(vectorとC言語スタイルの配列の両方)で使える、汎用的な検索関数 custom_find を実装します。

完成コード

#include <iostream>
#include <vector>
#include <string>

using namespace std;

// 1. イテレータを引数に取る、汎用的な検索関数テンプレート
template <class InputIterator, class T>
InputIterator custom_find(InputIterator first, InputIterator last, const T& value) {
    // firstがlastに到達するまでループ
    while (first != last) {
        // イテレータを間接参照(*)して、指し示す先の値を取得
        if (*first == value) {
            return first; // 値が見つかったら、その位置のイテレータを返す
        }
        // イテレータを一つ進める
        ++first;
    }
    return last; // 見つからなければ、範囲の最後の次を返す
}

int main() {
    // --- std::vectorで試す ---
    vector<string> items = {"りんご", "みかん", "ぶどう"};
    
    // 2. コンテナの.begin()と.end()でイテレータを取得して渡す
    auto it = custom_find(items.begin(), items.end(), "みかん");
    
    // 3. 結果のイテレータをチェック
    if (it != items.end()) {
        cout << "vector内で「" << *it << "」を見つけました。" << endl;
    }

    // --- C言語スタイルの配列で試す ---
    int numbers[] = {10, 20, 30, 40, 50};
    
    // 2. C配列のポインタは、イテレータとして振る舞う
    int* p_found = custom_find(numbers, numbers + 5, 30);

    // 3. 結果のポインタをチェック
    if (p_found != numbers + 5) {
        cout << "C配列内で「" << *p_found << "」を見つけました。" << endl;
    }
    
    return 0;
}

コードの解説

1. 汎用的な検索関数 custom_find

template <class InputIterator, class T> は、この関数が様々な型のイテレータや値に対応できる関数テンプレートであることを示します。

  • while (first != last): イテレータは、コンテナの「最後の要素の」を指す特別なイテレータ(end()が返すもの)と比較することで、範囲の終わりに達したかを判定します。
  • *first: ポインタと同様に、アスタリスク *(間接参照演算子)を使って、イテレータが指し示している先の要素の値を取得します。
  • ++first: ポインタと同様に、インクリメント ++ することで、イテレータを次の要素に進めます。

2. イテレータの取得

  • items.begin(), items.end(): vectorなどの標準コンテナは、.begin()メンバ関数で先頭要素を指すイテレータを、.end()メンバ関数で最後の要素の次を指すイテレータを取得できます。
  • numbers, numbers + 5: C言語スタイルの配列では、配列名が先頭要素へのポインタとして機能し、ポインタ演算で最後の要素の次を指すことができます。ポインタもイテレータの一種です。

custom_find関数は、引数が vector のイテレータであろうと、C言語配列のポインタであろうと、同じように動作します。これが、イテレータを介してアルゴリズムとコンテナを分離するC++の設計の強力さです。

その他のイテレータ取得メンバ関数

関数説明
cbegin(), cend()中身を変更しない読み取り専用のイテレータ (const_iterator) を返す
rbegin(), rend()コンテナを逆順に辿るためのリバースイテレータを返す
crbegin(), crend()読み取り専用のリバースイテレータを返す

まとめ

今回は、C++のイテレータの基本的な概念について解説しました。

  • イテレータは、コンテナの要素を指し示す、汎用的なポインタのようなもの。
  • * で値にアクセスし、++ で次に進む、という統一的なインターフェースを提供する。
  • コンテナは .begin().end() で、処理範囲を示すイテレータを提供する。
  • この仕組みにより、アルゴリズムとコンテナが分離され、コードの再利用性が高まる。

イテレータは、C++の標準ライブラリ(STL)を効果的に使いこなす上で、避けては通れない非常に重要な概念です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次