Standard Template Library (STL) は、プログラミング言語C++の規格で定義された標準ライブラリの一つ。ヒューレット・パッカード社在籍の研究者(当時)であったアレクサンドル・ステパノフ等によって考案され、後にANSI/ISO標準に組み込まれた。

概要

編集

STLC++

使C++

STLSTLSTL調STLcontainer調STL

STLSTLC++

構成要素

編集

コンテナ

編集



vector



array

(*) 

deque

Double Ended QUEue

list



forward_list

(*) 

set



map

set

multiset

set

multimap

map

unordered_set

(*) 

unordered_map

(*) unordered_set

unordered_multiset

(*) unoredered_set

unordered_multimap

(*) unoredered_map

(*)C++11

vectorarrayCvnvector<char>&v[n - 1] - &v[0] == sizeof(char) * (n - 1)array

unorderedunordered_set/unordered_maphash_set/hash_maphash_set/hash_map

C++basic_stringSTLSTL

コンテナアダプタ

編集

stack

(FILO; First In, Last Out)

queue

(FIFO; First In, First Out)

priority_queue



STLSTL

イテレータ

編集

STL

STL

InputIterator

InputIteratoristream_iterator

OutputIterator

OutputIteratorostream_iterator

ForwardIterator

ForwardIteratorInputIteratorOutputIterator

BidirectionalIterator

ForwardIteratorBidirectionalIteratorlistsetmultisetmapmultimap

RandomAccessIterator

BidirectionalIteratorRandomAccessIteratorvectorarraydequeSTLvectorarraydequenO(1)O(n)

(++it)(it1 != it2)(*it)

アルゴリズム

編集

STLで言うアルゴリズムは一般的なアルゴリズムより限定された用語であり、イテレータで指定されたコンテナの要素に対して特定の操作を行う関数である。

STLのアルゴリズムは標準で定義されているものだけでも多数あり、100以上の強力なアルゴリズムが用意されている。

std::vector<int> v1(3), v2(3);
v1[0] = 2;
v1[1] = 1;
v1[2] = 7;
std::copy(v1.begin(), v1.end(), v2.begin());

copySTLv1v2 vector<int>list<int>set<float>vector<double>

関数オブジェクト

編集

関数オブジェクトoperator()(関数呼び出し演算子)をオーバーロードしたクラスの一種であり、オブジェクトでありながら関数のように呼び出せるという特徴を持つ。ファンクタ (functor) とも呼ばれる。

関数オブジェクトの定義は例えば以下のようなものである。

struct square
{
    template<typename T>
    T operator()(T n) const { return n * n; }
};

使使CqsortSTLsort

STL使

C++11使

配列とポインタ

編集

STLの長所の一つにCの配列との親和性の高さがある。具体的にはポインタがそのままRandomAccessIteratorとして使用できる。実のところイテレータの走査の方法はポインタ演算を模倣して作られている。アルゴリズムで配列を扱う場合、配列の先頭要素を指すポインタが開始イテレータ、そのポインタに要素数を加算したものが終了イテレータになる。

std::vector<int> v(N);
const int N = 16;
int array[N]; // [0..15]

// このときarrayが配列の最初の要素へのイテレータ、
// array + Nが最後の要素の次へのイテレータとして使用できる。
std::copy(array, array + N, v.begin());

STLの欠点

編集

プログラムサイズの増大

編集

C++のテンプレートはテンプレート引数が違うとそれぞれ全く別の型として扱われ、それぞれ別の機械語コードにコンパイルされてしまう。

以下のようなプログラムをコンパイルすると、std::vector<int>のコードが作成される。

// vectorコンテナを使う
#include <vector>
 
std::vector<int> vecInt;

ここへさらに、

std::vector<double> vecDouble;

std::vector<double>std::vectorSTL使使intstd::vector<int>MyDynamicArrayOfIntdoublestd::vector<double>MyDynamicArrayOfDouble使使

PC

未対応コンパイラ

編集

STLはほとんど全ての要素がC++の比較的新しい機能であるテンプレートを用いて作られているので、テンプレート関連のC++標準への準拠度が低いコンパイラやテンプレート機能を持たないEmbedded C++では、一部に使用の制限があったりSTLの使用自体が不可能なことがある。

ただし2003年にはC++標準への準拠度が高められた最適化コンパイラであるVisual C++ Toolkit 2003マイクロソフトから無償配布されるなど、多くの環境ではテンプレートの利用における問題は少なくなってきている。

なお前述のコード量増大もそうであるが、これらはC++のテンプレート機能一般の問題であってSTL固有のものではない。

難解さ

編集

一般にSTLは柔軟で強力であると評価されているが、ライブラリを十分に生かしたプログラミングを行おうとすると、従来のC/C++プログラミングからは大きく離れた考え方や書法が必要になる。そのため、STLの使用経験を持たないプログラマには、一見して何をしているのか全くわからないソースコードになってしまうことがある。それは例えば以下のようなものである。

size_t N = 0;
int *pdata = NULL;
GetData(&pdata, &N); // データとデータ数を得る
 
typedef std::deque<int> Cont;
Cont deq(pdata, pdata + N);
FreeData(&pdata, &N); // データを解放

// 典型的なSTLコード
deq.erase(
        std::partition(
                deq.begin(),
                deq.end(),
                std::bind1st(std::less<Cont::value_type>(), 20)
        ),
        deq.end()
);

APIdequedeque20

typedef使STL使

使

歴史

編集

STL19791971(Dave Musser)

R&D((Deepak Kapur))

()Ada1987AdaAdaC++()C++使C/C++

AT&T(HP)C(C++)1992(Meng Lee)HP

(Andrew Koenig)199311ANSI/ISOC++HP19943

()()19947ANSI/ISO[1]

17ANSI/ISO C++(1727)stringC++

STLSTLSTL(Atul Saini)STL(Modena Software Incorporated)

STL1994[?]

脚注

編集

注釈

編集
  1. ^ 本件についての詳細は1995年3月に発刊されたDr. Dobb's Journalに掲載されているアレクサンドル・ステパノフへのインタビューで確認できる[1]

出典

編集
  1. ^ Al Stevens (March 1995). “Al Stevens Interviews Alex Stepanov”. Dr. Dobb's Journal. 

関連項目

編集