回答:
std::initializer_list格納することを意図したものではなく、単に...初期化のためのものです。内部的には、最初の要素へのポインタとサイズを格納するだけです。コードでは、std::stringオブジェクトは一時的なものであり、initializer_listどちらもオブジェクトの所有権を取得したり、オブジェクトの寿命を延ばしたり、オブジェクトをコピーしたりしないため(コンテナーではないため)、作成後すぐにスコープから外れますが、オブジェクトinitializer_listへのポインターは保持されます。そのため、セグメンテーション違反が発生します。
保存には、std::vectorまたはのようなコンテナを使用する必要がありますstd::array。
initializer_listます。move-onlyオブジェクトを使用することはできないため、たとえば、unique_ptrのベクターでlist initを使用することはできません。のサイズはinitializer_listコンパイル時の定数ではありません。そして、完全に異なることstd::vector<int>(3)をstd::vector<int>{3}行うという事実。私を悲しくさせます:(
もう少し詳細を追加します。基になる配列はstd::initializer_list、一時的なものと同様に動作します。次のクラスについて考えてみます。
struct X
{
X(int i) { std::cerr << "ctor\n"; }
~X() { std::cerr << "dtor\n"; }
};
次のコードでのその使用法:
std::pair<const X&, int> p(1, 2);
std::cerr << "barrier\n";
プリントアウト
ctor
dtor
barrier
最初の行から、型の一時的なインスタンスXが作成され(コンストラクタをから変換することにより1)、同様に破棄されます。に格納された参照pはぶら下がります。
についてはstd::initializer_list、次のように使用すると、
{
std::initializer_list<X> l { 1, 2 };
std::cerr << "barrier\n";
}
次に、基になる(一時的な)配列が存在する限り存在しlます。したがって、出力は次のようになります。
ctor
ctor
barrier
dtor
dtor
ただし、
std::pair<std::initializer_list<X>, int> l { {1}, 2 };
std::cerr << "barrier\n";
出力は再びです
ctor
dtor
barrier
基礎となる(一時的な)配列は最初の行にのみ存在するためです。lthen の要素へのポインタを逆参照すると、未定義の動作が発生します。
ライブデモはこちらです。
std::pair。