C++ STL チュートリアル

C++ 標準テンプレートライブラリ(Standard Template Library、STL)は、強力な C++ テンプレートクラスと関数の集合であり、汎用的で再利用可能な一連のアルゴリズムとデータ構造を提供します。

STL の設計はジェネリックプログラミングに基づいており、テンプレートを使用することで、特定のデータ型に依存しないコードを記述できることを意味します。

STL は複数のコンポーネントに分かれており、コンテナ(Containers)、イテレータ(Iterators)、アルゴリズム(Algorithms)、関数オブジェクト(Function Objects)、アダプタ(Adapters)などが含まれます。

STL を使用する利点:

  • コードの再利用:STL は多数の汎用データ構造とアルゴリズムを提供し、コードを繰り返し記述する作業を減らすことができます。
  • パフォーマンスの最適化:STL のアルゴリズムとデータ構造は、最高のパフォーマンスを提供するために最適化されています。
  • ジェネリックプログラミング:テンプレートを使用することで、STL はジェネリックプログラミングをサポートし、アルゴリズムとデータ構造をあらゆるデータ型に適用できます。
  • 保守が容易:STL の設計により、コードはよりモジュール化され、読みやすく保守しやすくなります。

C++ 標準テンプレートライブラリの核心には、以下の重要なコンポーネントが含まれています:

コンポーネント 説明
コンテナ(Containers)

コンテナは STL の最も基本的なコンポーネントの1つであり、ベクタ(vector)、リンクリスト(list)、キュー(queue)、スタック(stack)、集合(set)、マップ(map)などのさまざまなデータ構造を提供します。これらのコンテナは異なる特性と用途を持っており、実際のニーズに応じて適切なコンテナを選択できます。

アルゴリズム(Algorithms) STL は、コンテナ内の要素に対してさまざまな操作(ソート、検索、コピー、移動、変換など)を行うための多数のアルゴリズムを提供します。これらのアルゴリズムは、使用時にコンテナの具体的な型を気にする必要はなく、操作する範囲を指定するだけで済みます。
イテレータ(iterators) イテレータはコンテナ内の要素を走査するために使用され、コンテナの内部実装の詳細を気にせずに、コンテナ内の要素に統一的にアクセスできます。STL は、ランダムアクセスイテレータ、双方向イテレータ、前方向イテレータ、入出力イテレータなど、さまざまなタイプのイテレータを提供します。
関数オブジェクト(Function Objects) 関数オブジェクトは、関数のように呼び出すことができるオブジェクトであり、アルゴリズム内のさまざまな操作に使用できます。STL は、単項関数オブジェクト、二項関数オブジェクト、述語など、さまざまなニーズを満たす複数の関数オブジェクトを提供します。
アダプタ(Adapters) アダプタは、あるコンテナまたはイテレータを別のコンテナまたはイテレータに適合させて、特定のニーズを満たすために使用されます。STL は、スタックアダプタ(stack adapter)、キューアダプタ(queue adapter)、優先度付きキューアダプタ(priority queue adapter)など、さまざまなアダプタを提供します。

これらの各コンポーネントには豊富な定義済み関数が含まれており、複雑なタスクを簡単な方法で処理するのに役立ちます。


コンテナ

コンテナはデータを格納するためのシーケンスであり、さまざまな格納方法とアクセスモードを提供します。

STL のコンテナは3つのカテゴリに分類できます:

1. シーケンスコンテナ:要素のシーケンスを格納し、双方向の走査が可能です。

  • std::vector:動的配列であり、高速なランダムアクセスをサポートします。
  • std::deque:両端キューであり、高速な挿入と削除をサポートします。
  • std::list:リンクリストであり、高速な挿入と削除をサポートしますが、ランダムアクセスはサポートしません。

2. 連想コンテナ:キーと値のペアを格納し、各要素にはキー(key)と値(value)があり、キーによって要素が整理されます。

  • std::set:集合であり、重複する要素を許可しません。
  • std::multiset:マルチ集合であり、複数の要素が同じキーを持つことを許可します。
  • std::map:マップであり、各キーは1つの値にマッピングされます。
  • std::multimap:マルチマップであり、キーと値のペア(pair)を格納します。キーは一意ですが、値は重複可能で、1つのキーが複数の値にマッピングされることを許可します。

3. 非順序コンテナ(C++11 で導入):ハッシュテーブルであり、高速な検索、挿入、削除をサポートします。

  • std::unordered_set:非順序集合。
  • std::unordered_multiset:非順序マルチ集合。
  • std::unordered_map:非順序マップ。
  • std::unordered_multimap:非順序マルチマップ。

次のプログラムは、ベクタコンテナ(C++ 標準のテンプレート)を示しています。これは配列と非常に似ていますが、唯一の違いは、ベクタがサイズを拡張する必要があるときに、自動的に自身のストレージ要件を処理することです:

サンプル

#include <iostream> #include <vector> using namespace std; int main() { // int を格納するベクタを作成 vector<int> vec; int i; // vec の元のサイズを表示 cout << "vector size = " << vec.size() << endl; // ベクタに5つの値をプッシュする for(i = 0; i < 5; i++){ vec.push_back(i); } // vec を拡張した後のサイズを表示 cout << "extended vector size = " << vec.size() << endl; // ベクタ内の5つの値にアクセス for(i = 0; i < 5; i++){ cout << "value of vec [" << i << "] = " << vec[i] << endl; } // イテレータ iterator を使用して値にアクセス vector<int>::iterator v = vec.begin(); while( v != vec.end()) { cout << "value of v = " << *v << endl; v++; } return 0; }

上記のコードをコンパイルして実行すると、次の結果が生成されます:

vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4

上記のサンプルで使用されているさまざまな関数については、注意すべき点がいくつかあります:

  • push_back( ) メンバ関数は、ベクタの末尾に値を挿入し、必要に応じてベクタのサイズを拡張します。
  • size( ) 関数はベクタのサイズを表示します。
  • begin( ) 関数は、ベクタの先頭を指すイテレータを返します。
  • end( ) 関数は、ベクタの末尾を指すイテレータを返します。

STL は C++ プログラミングに不可欠な部分であり、C++ の機能を大幅に拡張し、プログラマーがより効率的で読みやすいコードを記述できるようにします。

STL の使い方を習得することは、あらゆる C++ プログラマーにとって非常に重要です。

その他の拡張