
10月も終わりに近づき、秋らしさを日々実感しちゃいますね。

こんにちは、ハラです。
今日は、STL(Standard Template Library)について書いてみたいと思います。
STLとは、C++の標準ライブラリにも含まれているコンテナと
アルゴリズムに関するライブラリのことです。
コンテナは、動的な配列やリスト、連想配列などのデータの入れ物

アルゴリズムは、ソートやマージなどなど、上のコンテナに使うものです

上手く使えば、短い時間で良いプログラムが書けてしまう便利なものです

そこで、STLの機能を知っていて使おうかなと思っている方、もしくは使い始めたばかりの方向けに、コンテナの1つ、vectorについての小ネタを書いてみます

それでは、小ネタに移ってみましょう〜


vectorは配列の代わりに使うことが多いため、下のようなループを書くことがあります。
void TestFunc(std::vector< Data >& dataVec)
{
for( size_t i = 0; i < dataVec.size(); i++ ) {
dataVec[i].get();
// 何かの処理
dataVec[i].set();
}
}
ループの中身は、sizeメソッドの呼び出しを除いて普通の配列と同じかと思います。
でも、この見慣れたコードに対してデバッグを行うと見慣れないことが起きるかもしれません

環境によっては、デバッガで「dataVec[i]」の値を直接見ることが出来ない場合があるのです

ちなみに、私の手元の環境では見れませんでした

この状況を解決するため、以下の変更を加えてみました

void TestFunc(std::vector< Data >& dataVec)
{
for( size_t i = 0; i < dataVec.size(); i++ ) {
Data& data = dataVec[i]; // ここで一時変数に入れてます
data.get();
// 何かの処理
data.set();
}
}
これは、以前の日記で書かれていたことと同じ変更ですが、
今回は、デバッガで値が見れるようにもなります

このコードをデバッガで動かすと、「dataVec[i]」の値は見れなくとも「data」の値は見ることが出来るため、中身の確認が出来るようになるというわけです。
1行追加することで意外な効果がありますね。

vectorには、push_backメソッドという、末端に要素を追加する便利な機能があります。
便利ではありますが、vectorには格納できる要素数を超えた場合、
自動でサイズを拡張する性質があるのでちょっと注意が必要です

例えば・・・・
std::vector< int > valueVec;
for( int = 0; i < 1000; i++ ) {
valueVec.push_back(i);
}
と書いた場合、ループを抜けるまでに複数回のサイズの拡張が行われることになります。
サイズの拡張とは、
・新しいメモリ領域の確保
・古いメモリから新しいメモリへのコピー
・古いメモリ領域の開放
が1セットとなって行われます。
う〜〜ん、出来れば避けたいものです

そこで、reserveメソッドを使って事前に格納できる要素数を増やしておきます。
std::vector< int > valueVec;
valueVec.reserve(1000);
for( int = 0; i < 1000; i++ ) {
valueVec.push_back(i);
}
この変更を加えると、1000個までの要素を格納できるので、ループの中でサイズの拡張が行われることはなくなります

ちなみに、許容量を増やすだけなのでreserveメソッドを呼んだ直後の要素数は0ということにご注意ください。

ここまで書いておいてなぜ

vectorは、通常の配列と同じ使い方が出来る上に、サイズの取得や
要素の追加・削除、動的な拡張などが行える便利な物です。
便利なだけに「まずは使ってみよう」と考えてしまいますが、
立ち止まってみて、本当に必要か考えてみるのも良いかもしれません。
初めから必要なサイズが固定とわかっているなら、普通の配列という選択肢がありますし、
要素の追加削除が頻繁に行われるならlistという選択肢もあります。
必要な機能と状況に合わせて、使うかどうかを決めてみてください

STLのvectorを使おうと思っている方、使い始めた方、ちょっとは参考になったでしょうか?
機会があれば、他の機能についても触れてみたいと思います。