std::vector
読み:エスティーディー-ベクター
外語:std::vector

 標準C++ライブラリのうちSTLに含まれる、ベクター要素を扱うためのクラス配列と同様の機能を提供する。
目次

概要
 mallocnewと同様、配列の連続要素に相当する領域をヒープに確保する。領域は動的に確保され、自動的に解放をしてくれる。
 クラスは、ベクター要素に対するアクセスの他、追加や削除といった処理を提供する。

書式
 #include <vector>

特徴

利点
 mallocやnewと違い自動的に開放されるため、メモリーリークが起こらない。

メモリーの連続性
 C++ Standard Library Defect Report Listの第69項として、std::vectorのメモリー連続性について触れられている。
 69. Must elements of a vector be contiguous?
 Discussion:
 The issue is this: Must the elements of a vector be in contiguous memory?
 Proposed resolution:
 Add the following text to the end of 23.3.6 [vector], paragraph 1.
 The elements of a vector are stored contiguously, meaning that if v is a vector<T, Allocator> where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
 簡単に訳すと、次のようになる。
 69. ベクター要素は連続している必要があるか?
 議論:
 問題はこれです: ベクター要素は、連続したメモリー内に存在する必要があるか?
 決議案:
 23.3.6 [ベクター] 第1項の末尾に、次の文を追加する。
 ベクター要素は、vがvector<T, Allocator>で、何らかの型Tがbool以外の場合、0 <= n < v.size()の全てにおいて等式&v[n] == &v[0] + nに従うことを意味し、連続的に格納される。
 これによれば、「現在の」std::vectorにはメモリーの連続性はあると解釈できる。古い実装では連続していないかもしれないが、そのような古すぎる実装は無視するならば、連続性を理由にmallocやnewなどを使う理由はもはや無い。
 必要なだけstd::vectorでメモリーを確保すれば、それは&v[0]から連続したメモリー領域として扱うことができる。メモリーリークに怯える必要は、もはや無いのである。

処理時間
 ベクター要素へのアクセスと要素の追加は、定数時間(大きさに限らず常に一定時間)で完了する。
 特定の値の検出、ベクターへの要素挿入は、線形時間(入力の大きさに比例する時間)を要する。

ブール型のvector
 ビット値であるboolのvector、つまりvector<bool>は、標準C++ライブラリでは特殊化して処理している。
 複数のビットがパックして処理されることもあり(処理系依存)、メモリー効率がよいこともある。
 vector<bool>は、ビットを反転するメソッドとしてflip();が追加され、また演算子=がbool値を参照するようにオーバーロードされる。

仕様

コンストラクター
 文法は次の通り。
 vector();
 vector(size_type size);
 vector(size_type num, const TYPE &val);
 vector(const vector &from);
 vector(input_iterator start, input_iterator end);
 上から順に、次のようにベクターは作られる。

演算子
 文法は次の通り。
 v1 == v2
 v1 != v2
 v1 <= v2
 v1 >= v2
 v1 < v2
 v1 > v2
 v[]
 各ベクターは、比較演算子によって比較できる。
 各ベクターの個々の要素は[]演算子によって調べられる。先頭へのポインターが必要なら&v[0]で求められるが、C++11では、この目的のために新たにdata()というメソッドが追加された。

メソッド
assign()ベクターに要素を割り当てる
at()指定した位置の要素を返す
back()最終要素への参照を返す
begin()先頭を指すイテレーターを返す
capacity()ベクターが保持できる要素数を返す
clear()全ての要素を削除する
empty()ベクターが空ならtrueを返す
end()末尾の次を指すイテレーターを返す
erase()要素を削除する
flip()ビットを反転する (vector<bool>のみ)
front()先頭要素への参照を返す
get_allocator()ベクターのアロケーターを返す
insert()要素をベクターに挿入する
max_size()ベクターが保持できる最大要素数を返す
pop_back()最終要素を削除する
push_back()ベクターの末尾に要素を追加する
rbegin()ベクター末尾を指すリバースイテレーターを返す
rend()ベクター先頭を指すリバースイテレーターを返す
reserve()ベクターが保持できる要素数を設定する
resize()ベクターのサイズを変更する
size()ベクター中の要素数を返す
swap()二つのベクターを入れ替える

応用方法
 C++で、オプション文字列をUTF-8のstring型として扱う方法。
 〓や〓といった、シフトJISで表わせないものをファイル名としてオプションに渡す場合はUnicodeとしてオプションを受け取る必要があるが、Windows標準のUTF-16、つまりwchar_tでは処理が面倒なだけで何の利点もない。
 そこで、普段はUTF-8にして内部で持ち回し、必要な時には再びUTF-16にしてAPIを呼べばよいのである。
 CHogeAppクラスのアプリケーションと想定して説明する。
#include <vector>
#include <string>
 上の他に、必要なヘッダーファイルは逐一includeする(<windows.h>など)。
#ifdef _MSC_VER
int wmain(int argc, wchar_t *argv[])
{
    std::vector<std::string> args(argc);
    for (int idx = 0; idx < argc; ++idx)
    {
        int nLen = WideCharToMultiByte(CP_UTF8, 0, argv[idx], wcslen(argv[idx]), NULL, 0, NULL, NULL);
        std::vector<char> buf(nLen + 1);
        nLen = WideCharToMultiByte(CP_UTF8, 0, argv[idx], wcslen(argv[idx]), &buf[0], nLen, NULL, NULL);
        args[idx] = &buf[0];
    }
    CHogeApp theApp(argc, args);
    return (int)0;
}
#else
int main(const int argc, const char *argv[])
{
     std::vector<std::string> args(argc);
     for (int idx = 0; idx < argc; ++idx)
     {
         args[idx] = argv[idx];
     }
     CHogeApp theApp(argc, args);
     return EXIT_SUCCESS;
}
#endif
 まず必要なmain関数は上記の通りである。Windowsではwmain関数でUTF-16形式のオプション文字列が得られる。UNIX(BSDやLinux等)はいい加減なので、UTF-8環境であればそのままUTF-8の文字列がchar *で得られるため、それをそのままstd::stringに代入する。
CHogeApp::CHogeApp(const int argc, const std::vector<std::string> &args)
{
    Main(argc, args);
}
CHogeApp::~CHogeApp()
{
}
 コンストラクターとデストラクターは必要に応じて内容を書き換える。主処理はCHogeApp::Mainとする。
void CHogeApp::Main(const int argc, const std::vector<std::string> &args)
{
...
}
 Main関数以降に必要な処理を書けばよい。この時点で、argcの他に、std::string型の引数が得られている。
 std::vectorなので、手動でのメモリー解放は不要。また、参照はargs[0]のように、char *型の時と変わらない。先頭アドレスが欲しいときは&args[idx][0]のようにする。

再検索