まずは アッサリさっくりと...
この程度覚えとけば、適当なサマになるものを
なにかしら作れるだろう程度の内容です。
下でよく使われている
A〜Bの範囲とは、厳密に言うと、
A〜(B-1)の範囲です。
巷の文献記号で書くと、[A,B)のことです。
-
〔UITILITY〕
■typename T::Subtype Value
#インクルードなし(C++標準実装)
template<class T>の内部型 Subtype が明瞭でない場合に「これは型名だぞ」と明示させる。
■pair<class T1,class T2> value(const T1 first, const T2 second)
#include <utility>
※ make_pair(first,second)で一つのpairを暗黙的に生成できる。
-
2つの型にアクセス可能な1つのオブジェクトを生成する。
-
value.first で1番目の要素、value.second で2番目の要素にアクセスできる。
■auto_ptr<class T> ptr(new T)
#include <memory>
-
ptr をスコープ内部で自動変数化したTのスマートポインタを生成。
-
個々のメソッドについては、ptr->でアクセスする(もしくは、(*ptr).でアクセス)。
-
ptr.get()で元オブジェクトの取得が出来る。
■min/max
#include <algorithm>
template <class T, class Compare> T min(const T&a,
const T&b), max(const T&a, const T&b)
template <class T, class Compare> T min(const T&a, const
T&b, Compare comp)
template <class T, class Compare> T max(const T&a, const
T&b, Compare comp)
-
最小/最大値を返す。
-
使用時は、型の不一致エラーをコンパイルが出す場合などの時に min<long>(a,b)
のように、強制的に<型>を明示することもできる。
-
Compare は、関数オブジェクト型。 bool comp(a,b) で a<b の時、真値を返さなければならない。
■void swap(T& a, T& b)
#include <algorithm>
■using namespace std::rel_ops
#include <utility>
-
上記を宣言すると、そのスコープ内部で全ての未定義比較演算子について、==、< の演算子さえ定義してやれば、残りの
!=、>、<=、>= は、自動的に定義される。
■offsetof()
#インクルードなし(C++標準実装)
構造体、または、共用体のメンバのオフセット値を表す。
〔STL〕Standard Template Library
■vector<T> value
#include <vector>
![](stl-vector.gif)
-
value.push_back(T) で要素を後方へ追加。
-
value.pop_back() で要素の最後を削除。
-
value.size()は、要素の個数を表す。
-
value.resize(n) でサイズ調整。
-
value[i] で各要素へアクセス。
■deque<T> value
#inclue <deque>
![](stl-deque.gif)
-
value.push_front(T) で要素を前方へ追加。
-
value.push_back(T) で要素を後方へ追加。
-
value.pop_front() で一番最初の要素を削除する。
-
value.pop_back() で一番最後の要素を削除する。
-
value.size() は、要素の個数を返す。
-
value.resize(n) でサイズ調整。
-
value[i] で各要素へアクセスする。
■反復子(iterator)
-
*演算子 - その位置にある要素を返す。
-
-> 演算子 - 要素メンバへアクセスする。
-
++ 演算子 - 反復子を次の要素へ進める。
-
-- 演算子 - 反復子を前の要素へ戻す。
-
==、!= 演算子 - 反復子が同じ位置であるかどうか。
-
= 演算子 - 反復子に代入する。
-
container.begin() - 先頭の反復子を返す。
-
container.end() - 末端の反復子を返す。 末端とは、終端より一つ進めた存在しないオブジェクトを指し示す。
範囲を指定する処理についても、それは同じことを意味する。
-
反復子にインクルメント演算子を使う場合(++)、++iterator を使った方が、iterator++
を使うより速い。 iterator++ を利用すると、古い要素を参照するオーバーヘッドが生じる。
-
vector、dequeの反復子は、要素の追加、削除、再割り当てが行われると無効になる。
<シンプルな一例>
vector<T> vect;
for(vector<T>::iterator iter = vect.begin(); iter != vect.end() ; ++iter) {
・・・
}
|
■逆反復子(rbegin()/rend())
-
container.rbegin() - 逆方向の先頭の反復子。
-
container.rend() - 逆方向の末端の反復子。
![](stl-rbegrend.gif)
■list<T> value
#include <list>
![](stl-list.gif)
-
value.push_back(T)/.push_front(T) で要素追加。
-
value.pop_back()/.pop_front() で要素の削除。
-
ランダムアクセス出来ないので、 list<T>::iterator を利用する。
-
value.empty() で空チェック。
-
value.size() で要素数取得。
-
value.resize(n) で調整可能。
■set/multiset<T,比較テンプレート> value
#include <set>
![](stl-set.gif)
-
set は、要素の重複を許さないが、 multiset は、要素の重複を許す。
-
insert(T) で項目を追加する。 項目は、比較テンプレートに応じてソートされ挿入される。
-
ランダムアクセスできないので、反復子を利用する。
-
比較テンプレートは、 bool Compare(const T &a, const T &b) 型の関数オブジェクト。
真値を返せば、aはbより前に来る。
■map/multimap<T1,T2,比較テンプレート> value
#include <map>
![](stl-map.gif)
-
キーと値のペアで要素を構成する。
-
insert(make_pair(T1,T2)) で項目を追加する。
-
map は、キーの重複を許さないが、multimap は、キーの重複を許す。
-
ランダムアクセス出来ないので、反復子を利用する。
-
要素へのアクセスは、iter->first がキー、iter->second が値を表す。
-
要素への追加は、value[T1] = T2 としても良い。
-
〔ALGORITHM〕#include <algorithm>
■min_element/max_element ( iteratorA, iteratorB )
-
A〜Bの範囲で、最小/最大を表す要素の反復子を返す。
■sort ( iteratorA, iteratorB 【,func】)
sort ( iteratorA, iteratorB )
sort ( iteratorA, iteratorB, func )
A〜Bの範囲を func(T1,T2) の戻り値で判断して並び替える。 T1<T2 のときに真値を返せば、T1 は T2 より前に来る。
■find ( iteratorA, iteratorB, T)
■reverse ( iteratorA, iteratorB )
■equal ( iteratorA, iteratorB, iteratorA2 )
-
A〜Bの範囲をA2から比較して全く等しいものかどうかを真偽で返す。
■copy ( iteratorA, iteratorB, iteratorA2 )
-
A〜Bの範囲をA2へ複写する。
-
A2から指定された反復子には、A〜B分の要素をコピーできるだけの要素が事前に存在しなければならない。
-
A2に要素が存在しない場合は、back_inserter()等の反復子を利用する。
■挿入反復子( back_inserter/front_inserter/inserter )
A front_inserter ( container )
push_front() により、同順で挿入される。
B inserter ( contrainer, iterator )
insert() により、iterator の位置へ同順で挿入する。
一つ先に進める++演算子は、この3種類の反復子については、全く影響を受けない。
■ストリーム反復子(入出力ファイル用) istream_iterator/ostream_iterator
・istream_iterator<型名>(入力元)
・入力元の始点を表す。 ( e.g. istream_iterator<string>(cin)
)
・istream_iterator()
・入力元の終点を表す。
・ostream_iterator<型名>( 出力先, "区切り文字列" )
・出力先を表す。 ( e.g. ostream_iterator<string>(out,"\n")
)
■end = remove( iteratorA, iteratorB, T )
-
A〜Bの範囲中でTと一致する値を抹消する。
-
抹消する処理は、要素を切り詰めるだけで、サイズの変更は行われない。 サイズ調整まで完璧に行うには、remove()
が返す戻り値の位置まで erase() する必要がある。
coll.erase(iteratorB, end)
連想コンテナでは使用できない。
■container.erase( iteratorA, iteratorB )
<例> coll.erase(remove(coll.begin(),coll.end(),value),coll.end())
■container.erase(T)
■func for_each( iteratorA, iteratorB, func )
-
A〜Bの範囲の要素を func(T) する。 ※ T:=各要素
■generate_n( iterator, n, op )
-
iteratorの位置から始めて、op() を n 個上書きする。
■generate( iteratorA, iteratorB, op )
-
A〜Bの範囲の要素を、op() でそれぞれ上書きする。
■transform( iteratorA, iteratorB, iteratorA2, func )
-
A〜Bの範囲の要素を func(T) した戻り値で A2 を始点として上書きする。
-
iteratorA2には、十分な要素があらかじめ設けられているか、もしくは、挿入反復子を利用しなければならない。
■transform( iteratorA, iteratorB, iteratorA2, iteratorA3, func )
-
A〜Bの範囲の要素を func( T, T2 ) した戻り値で A3 を始点として上書きする。
-
iteratorA2には、十分な要素があらかじめ設けられていなければならない。
-
iteratorA3には、十分な要素があらかじめ設けられているか、もしくは、挿入反復子を利用しなければならない。
■find_if( iteratorA, iteratorB, func )
-
A〜Bの範囲を func(T) した戻り値が真の場合にその反復子を返す。
■less<T>
-
less<T>( V1, V2 ) が V1<V2 なら真値を返す。
■greater<T>
-
greater<T>( V1, V2 ) が V1>V2 なら真値を返す。
■negate<T>()
-
negate<T>()(V) は、 -V を返す。
■multiplies<T>()
-
multiplies<T>()(V1,V2) は、 V1*V2 を返す。
■replace_if( iteratorA, iteratorB, compare, newValue )
-
A〜Bの範囲を compare(T) した結果が真値であれば、 newValue で置き換える
■equal_to<T>(V1,V2)
■mem_fun_ref(&class::offset)(T)
-
class::offset(T) を実行させる。 ( class T であることが必須条件 )
<例> for_each(coll.begin(),coll.end(),mem_fun_ref(&Person::save))
※各々の要素は、Personから派生したものでなければならない。
![](../../cycode-menisys.gif)