CppCon 2018でのNicolai Josuttisの「C++での初期化の悪夢」プレゼンテーションには、ある時点で次のコードが含まれていました。
std::vector< std::string > v07 = {{ "1", "2" }};
ニコライ 次のように言った (転写鉱山):
問題は、ここで何が起こるか、これらの2つのパラメーターをiteratorsとして解釈することです。したがって、これらは反復子なので、thisが範囲の始まりであり、thisは範囲の終わりであり、同じ範囲のcharactersを参照する必要があります。文字は暗黙的に文字列に変換されるため、これはコンパイルされます。運がよければ、コアダンプを取得できます。そうでない場合は、大きな問題があります。
彼はそこで私を失いました。誰かがここで何が起こっているのか、正確にステップごとに説明できますか?
以下のコード
_std::vector< std::string > v07 = { { "1", "2" } };
_
に等しい
_std::string s = {"1","2"}; // call string(const char*, const char*)
std::vector<std::string> v07 = {s}; // initializer list with one item
_
問題は
_ s={"1","2"};
_
これはstring(const char* start, const char* end)
コンストラクターを呼び出しますが、start
とend
は同じ文字列オブジェクトを参照する必要があります。 "1"と"2"は2つの異なるオブジェクトであるため、UBにつながります。