最初にCスタイルの文字列を構築してから(それを使用して)std :: stringを作成するのではなく、文字のベクトルから文字列を初期化するためのより速い/代替/「より良い」方法はありますか?
最初にCスタイルの文字列を構築してから(それを使用して)std :: stringを作成するのではなく、文字のベクトルから文字列を初期化するためのより速い/代替/「より良い」方法はありますか?
回答:
C ++ 11を使用するstd::string(v.data())か、ベクトル'\0'の最後にaが含まれていない場合は、を使用できますstd::string(v.data(), v.size())。
string(&v[0], v.size())また動作しますが、後にのみ必要がありassert(not v.empty());、ベクトルが空の場合以来、両方v[0]とv.front()未定義の動作を呼び出します。これは、address-of演算子を使用する必要がないという構文上の単純さを除けばdata()、空のベクトルでも機能するC ++ 11の関数の真の利点です。
std::string(v.data())、長い文字列になる可能性があります。したがって、この方法は使用しないでください。
std::string(v.data(), v.size())その正確な理由で回答で明示的に言及されていたの何が問題になっていますか?
std::string s(v.begin(), v.end());
ここで、vはほとんど反復可能です。(具体的には、begin()およびend()はInputIteratorsを返す必要があります。)
完全std::string(&v[0])を期すために、もう1つの方法があります(ただし、文字列がnullで終了していることを確認する必要があり、std::string(v.data())一般的に推奨されます。
違いは、前者の手法を使用して、バッファーを変更する関数にベクターを渡すことができることです。これは、.data()では行えません。
data()バッファの変更に使用できないのですか?data()非constベクトルを呼び出すとaが返されるように見えT *ます(そして、ベクトルがconstの場合、T const &とにかく'v [0] `が返されます)。
v文字列の場合も同様ですが、ターゲットタイプは文字列でvあり、ベクトルです。(しかし、C ++ 17が文字列をベクトルと同等にすることは素晴らしいことです。)
私はステファンの答えが好きです(Sep 11 '13)が、少し強くしたいと思います。
ベクトルがnullターミネーターで終わる場合は、(v.begin()、v.end())を使用しないでください。v.data()(またはC ++ 17より前のバージョンの場合は&v [0])を使用してください。 。
vにnullターミネーターがない場合は、(v.begin()、v.end())を使用する必要があります。
begin()とend()を使用し、ベクトルに終了ゼロがある場合、たとえば、文字列「abc \ 0」で終わることになります。たとえば、長さが4ですが、実際には「abc」のみでなければなりません。
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());
std::vector<char> v2(std::move(v))a と同じことを行うものstd::stringです。