標準テンプレートライブラリ(STL)は、元々はアレクサンダー・ステパノフがC++プログラミング言語用に設計したソフトウェアライブラリで、 C++標準ライブラリの多くの部分に影響を与えましたが、現在は積極的にメンテナンスされておらず、ほとんどがC++標準ライブラリ自体に統合されています。STLは、アルゴリズム、コンテナ、ファンクタ、イテレータと呼ばれる4つのコンポーネントを提供します。[ 1 ]
STLは、コンテナや連想配列など、C++用の共通クラス群を提供します。これらのクラスは、基本的な操作(コピーや代入など)をサポートする組み込み型やユーザー定義型であれば、どれでも使用できます。STLのアルゴリズムはコンテナに依存しないため、ライブラリの複雑さが大幅に軽減されます。
STLはテンプレートを用いることでその性能を実現しています。このアプローチはコンパイル時のポリモーフィズムを提供し、多くの場合、従来の実行時ポリモーフィズムよりも効率的です。最新のC++コンパイラは、STLの多用によって生じる抽象化によるペナルティを最小限に抑えるように調整されています。
STLは、C++用の汎用アルゴリズムとデータ構造の最初のライブラリとして、汎用プログラミング、効率を損なわない抽象性、フォン・ノイマン計算モデル[ 2 ]、値セマンティクスという4つのアイデアを念頭に置いて作成されました。
STLとC++標準ライブラリは2つの異なる実体である[ 3 ]が、STLから直接影響を受けたり継承されたりしたC++標準ライブラリの部分は「STL」と呼ばれることもある[ 4 ] 。
1993年11月、アレクサンダー・ステパノフは、汎用プログラミングに基づくライブラリをANSI/ISO C++標準化委員会に提出した。委員会の反応は圧倒的に好意的で、アンドリュー・ケーニッヒから1994年3月の会議に間に合うように正式な提案を提出するよう要請があった。委員会には変更や拡張に関する要望がいくつかあり、委員会のメンバーはステパノフとメン・リーと会合を開き、詳細を詰めた。最も重要な拡張(連想コンテナ)の要件は、完全に実装することで一貫性があることを示す必要があり、ステパノフはこの作業をデビッド・マッサーに委任した。提案は1994年7月のANSI/ISO委員会会議で最終承認を受けた。その後、ステパノフとリーの文書17はANSI/ISO C++ドラフト標準(1、条項17~27の一部)に組み込まれた。
1994年8月、ヒューレット・パッカード社がSTLの実装をインターネット上で無償公開することを決定したことで、STLの早期普及の見通しは大幅に改善された。標準化プロセス中にステパノフ、リー、マッサーによって開発されたこの実装は、今日、コンパイラやライブラリベンダーが提供する多くの実装の基礎となっている。
STLには、シーケンスコンテナと連想コンテナが含まれています。コンテナはデータを格納するオブジェクトです。標準のシーケンスコンテナvectorには、、、、dequeおよびがあります。標準の連想コンテナは、、、、、、、およびです。またlist、特定のsetインターフェースを持ち、他のコンテナを実装として使用するコンテナアダプタ、、、およびもあります。multisetmapmultimaphash_sethash_maphash_multisethash_multimapqueuepriority_queuestack
STL は 5 種類のイテレータを実装しています。これらは入力イテレータ(値のシーケンスを読み取るためだけに使用できます)、出力イテレータ(値のシーケンスを書き込むためだけに使用できます)、前方イテレータ(読み取り、書き込み、および前方への移動が可能です)、双方向イテレータ(前方イテレータに似ていますが、後方にも移動できます) です。ランダムアクセスイテレータ(1回の操作で任意の数のステップを自由に移動できる)。
STLの基本的な概念は範囲であり、これは計算の開始と終了を指定するイテレータのペアです。ライブラリのデータ構造を操作するアルゴリズムテンプレートのほとんどは、範囲を使用するインターフェースを備えています。[ 8 ]
双方向イテレータをランダムアクセスイテレータのように動作させることも可能です。例えば、10ステップ進むには、一度に1ステップずつ合計10回進むだけで済みます。しかし、個別のランダムアクセスイテレータを用意することで、効率面で有利になります。例えば、ベクトルにはランダムアクセスイテレータがありますが、リストには双方向イテレータしかありません。
イテレータは、STLの汎用性を実現する主要な機能です。例えば、シーケンスを反転させるアルゴリズムは双方向イテレータを使用して実装でき、同じ実装をリスト、ベクトル、デックにも適用できます。ユーザーが作成したコンテナは、5つの標準イテレータインターフェースのいずれかを実装するイテレータを提供するだけでよく、STLで提供されるすべてのアルゴリズムをコンテナ上で使用できます。
この汎用性には、時として代償が伴う。例えば、マップやセットといった連想コンテナに対して検索を行う場合、イテレータを用いるよりも、コンテナ自体が提供するメンバ関数を呼び出す方がはるかに処理速度が遅くなることがある。これは、連想コンテナのメソッドは内部構造に関する情報を利用できるのに対し、イテレータを用いるアルゴリズムではその内部構造が不透明であるためだ。
STLには、検索やソートなどの処理を実行するための多数のアルゴリズムが用意されており、それぞれが特定のレベルのイテレータを必要とするように実装されています(そのため、イテレータによるインターフェースを提供する任意のコンテナで動作します)。検索アルゴリズム(例:)は二分探索を使用しbinary_search、ソートアルゴリズム(例:)は、データ型が比較演算子を実装しているか、カスタム比較関数を指定する必要があります。このような比較演算子または比較関数は、厳密な弱順序付けを保証する必要があります。これらに加えて、要素の範囲からヒープを作成するアルゴリズム、要素の範囲の辞書順に並べられた順列を生成するアルゴリズム、ソートされた範囲をマージするアルゴリズム、およびソートされた範囲の和集合、積集合、差集合を実行するアルゴリズムも用意されています。lower_bound<
STLには、関数呼び出し演算子( )をオーバーロードするクラスが含まれています。このようなクラスのインスタンスは、ファンクタまたは関数オブジェクトと呼ばれます。ファンクタを使用すると、関連付けられた関数の動作をパラメータ化できます(たとえば、ファンクタのコンストラクタに渡される引数を介して)。また、ファンクタは、関数とともにファンクタごとの状態情報を保持するために使用できます。ファンクタと関数ポインタはどちらも関数呼び出しの構文を使用して呼び出すことができるため、対応するパラメータが関数呼び出しのコンテキストにのみ現れる場合、テンプレートの引数として互換性があります。operator()
特に一般的なファンクターの種類は述語です。たとえば、などのアルゴリズムは、シーケンスの要素に対して動作する単項find_if述語を受け取ります。sort、partial_sort、nth_elementなどのアルゴリズム、およびすべてのソート済みコンテナは、厳密な弱い順序付けを提供する必要のある二項述語を使用します。つまり、推移的で、非反射的で、非対称な二項関係に対するメンバーシップテストのように動作する必要があります。何も指定されていない場合、これらのアルゴリズムとコンテナはデフォルトでless を使用し、これにより、小なり演算子 < が呼び出されます。
C++コンパイラの実装品質(QoI)は、STL(および一般的にテンプレート化されたコード)の使いやすさに大きな影響を与えます。
その他の問題点としては、以下のものが挙げられます。
copy_ifアルゴリズムは省略されていますが、[ 14 ] C++11で追加されています。[ 15 ]STLは、
コンテナ
、
イテレータ
、
関数オブジェクト
、および
アルゴリズムで構成されています。
ライブラリのアルゴリズム テンプレートのほとんどは、データ構造を操作するため、範囲を使用するインターフェースを備えています。範囲とは、計算の開始と終了を指定するイテレータのペアです。[...]一般に、範囲 [i, j) は、i が指す要素から始まり、j が指す要素を含まないデータ構造内の要素を指します。範囲 [i, j) は、j が i から到達可能な場合に限り有効です。