STL

出典: YKAwiki

目次

概要

STL (Standard Template Library)についてのあれこれを書いていきます ・STLとはC++の標準ライブラリである。 ・STLはC++の売りの一つであるテンプレートによるコンテナ操作を主な機能としている ・std::stringはSTLとは関係ないらしい(template<>を使っていない) ・名前空間として"std"を使っている。使用時は

std::vector<int> indexList;

とするか、

using namespace std;
vector<int> indexList;

とする必要がある。

ただし、Visual C++ に付いてくるような標準のSTLに不満を感じたユーザによって、[[1]]や[[2]]といったものも開発されている。

C++版ガベッジコレクタのスマートポインタなど、標準STLよりも優れた点があるらしく乗り換えてるソフトも多くあります。

参考リンク

ぶっちゃけ下記サイトがかなり充実してる

http://www.wakhok.ac.jp/~sumi/stl/

std::vector

全ての基本形であるコンテナ。

std::vector<int> hoge;

で宣言して

int a = 10;
hoge.push_back(a);

と追加していき、

int index = 5;
int b = hoge[index];

で参照。 削除はどうだったかな…? 全削除は

hoge.clear();

注意点

名前

"list"は"std::list"という予約語なので、"using namespace std;"を宣言してる場合は使わない方がいい。

memcpyを使ってはいけない

vector、およびこれをメンバとして持つクラス・構造体同士をmemcpyでコピーしてはいけない。あとmemsetも危険。

そもそも、プラットフォーム依存の部分が大きいため、vectorなどコンテナクラスの内部はブラックボックスととらえるべきである。

なのでメモリコピーよりも以下のようにイコールで代入か、一個ずつ入れてやる方が確実。

class Hoge{
public:
 std::vector<int> indexes;
};
Hoge a, b;

//(中略)
a = b;

//あるいは
a.indexes = b.indexes;

//とはいえ、やはり
a.indexes.clear();
for(int i = 0; i < b.indexes.size(); i ++){
 a.indexes.push_back(b.indexes[i]);
}

//とか、
a.indexes.clear();
for(std::vector<int>::iterator it = b.indexes.begin(); it != b.indexes.end(); it ++){
 a.indexes.push_back((*it));
}

//とかの方が確実・安心。そのかわり超遅い
//きっと誰かがもっとスマートな方法を探し出してくれるはず!

クラス同士でイコール受け渡しすんのがいやなら

  • イコール演算子をprivate化、あるいは置き換え
  • あるいはコンストラクタ引数に指定してこぴらせる
  • あるいは"A.copy(B)"のようにコピー元を渡す関数を作る

のどれかでちゃんと指定してやってください。 STLコンテナが無い構造体&クラスならmemcpyのが確実&安全なんですが、STLが出てきた時点で諦めましょう。

ポインタをテンプレートの要素としたとき

具体的には

std::vector<int*> pointers;
const int SIZE = 10;
const int WIDTH = 640;
const int HEIGHT = 480;
for(int i = 0; i < SIZE; i ++){
 pointers[i] = new int[2];
 pointers[i][0] = rand() % WIDTH;
 pointers[i][1] = rand() % HEIGHT;
}

とかの状況ですね。 int*をテンプレートの型としています。 ここまでは何の問題はないですが、このvectorが破棄されるときどうなるのでしょうか。

勝手に解放してくれればいいですが、なにぶん機種依存&ブラックボックスなので自分で解放する必要があるでしょう。

for(int i = 0; i < pointers.size(); i ++){
 delete [] pointers[i];
}