vectorで表現するstring。
vectorで表現するstringを、vstringと呼んでみるテスト。
typedef std::vector<char> vstring;
コレで何がしたいのかと言うと、C文字列を表現したいのです。
ヌル文字で終端するアレ。
何故かと言えばやっぱり、可変長配列だから。
ほとんどの(凡人)プログラマがstringを使う理由はコレだと思うのです。
後はまぁ自分でnew/delete書かなくてイイとか。
以下vstringについてだらだらと。
文字列操作関数にバッファサイズ指定が要らなくなる。
//// キーワードを置換する関数。 // char配列版 void ReplaceKeyword(const char* src, const char* keyword, char* out, size_t outSize); // vstring版 void ReplaceKeyword(const vstring& src, const vstring& keyword, vstring& out);
関数内で、outのバッファサイズを気にしなくて良くなります。便利!
std::stringの文字列データは、連続したメモリにある事を保証していない。
更に、ヌル終端するとも保証されていません(Effective STL第16項参照)。
つまり以下のコードはダメ。
// 文字列をコピーする std::string src; std::string dst; dst.resize(src.size()); strcpy(&dst.at(0), src.c_str());
代入演算子使えよとかcopy()使えよとか言うツッコミは一旦置いときます。
第2引数に渡しているc_str()は、C形式の文字列を返却するので問題ないですが、
第1引数のatはダメ。
じゃあc_str()をconst_castするのはどうかと言うと、自分は未検証なのでわかりません(;゚∀゚)
でもポリシー的にあまりやりたいと思わないです。
要は、string非constなcharポインタを引数に取る関数とは、相性がよろしく無くて、
そんなのconst付ければいいじゃんって話なんですが、
constを付ける習慣がないC/C++プログラマはかなり多いんじゃないかと思うわけで、
実際今の職場ではかなり多いです。
絶対に変更されない値なんだけども、const付けない。
小規模なら全部書き換えもありえますが、大規模プロジェクトに途中参入だったり
するともうどうしようもないわけでして。
WIN32APIもstringとの相性は微妙と思います。
MultiByteToWideChar関数とかね。
そんな時に重宝するんですvstring。
↑のコードは、vstringでこんな感じに書き換えられます。
// 文字列をコピーする vstring src; vstring dst; dst.resize(src.size()); // srcはヌル終端になっているものとして。 strcpy(&dst[0], &src[0]);
使う時の注意点。
当たり前なんですが終端にヌル文字が要ります。
可変長でstringの様に使っていると、忘れがち。
配列が空の場合、&x[0]の返すポインタは未定義の動作を引き起こす。
Effective STL第16項にもある通り、以下の様なコードはダメ。
vstring vstr; // この時点ではサイズが0! char* c = &vstr[0]; // これが返すポインタは未定義の動作を引き起こす!