現在、私と私たちのチームが std::string を利用するためにリファクタリングしたくない複雑な関数があり、変更された char* が必要です。string::c_str() のディープコピーを char* に適切に作成するにはどうすればよいですか? 文字列の内部に保存されている char* を変更するつもりはありません。
char *cstr = string.c_str();
c_str() が const であるため失敗します。
既存の関数を変更するのではなく、ラッパーとして機能するオーバーロードを作成するだけです。既存の関数がret_type f(char *)
であると仮定すると、オーバーロードを次のように記述します。
ret_type f(std::string s) {
return f(&s[0]);
}
s
文字列のコピーを取得するために費やされる労力を最小限に抑えるために、参照ではなく値で渡すことに注意してください。
理論的には、C++03 までは、これが機能することが保証されていません (つまり、文字列のバッファーが連続していることが保証されていません)。実際には、委員会がその保証を追加するのはかなり簡単でした。主な理由は、それ以外のことを行う実装を誰も知らなかったからstd::string
です。
同様に、理論的には NUL ターミネータが欠落している可能性があります。その可能性が心配な場合は、代わりに使用するか、戻り値return f(const_cast<char *>(s.c_str()));
の前に追加できます。s.push_back('\0');
ret_type f(std::string s) {
s.push_back('\0');
return f(&s[0]);
}
明らかな解決策は次のとおりです。
std::vector<char> tmp( string.begin(), string.end() );
tmp.push_back( '\0' );
function( &tmp[0] );
(しかし、私はJerry Coffinのソリューションが好きです。)