Este código:
#include <iostream>
#include <string>
std::pair<std::initializer_list<std::string>, int> groups{ { "A", "B" }, 0 };
int main()
{
for (const auto& i : groups.first)
{
std::cout << i << '\n';
}
return 0;
}
compila pero devuelve segfault. ¿Por qué?
Probado en gcc 8.3.0 y en compiladores en línea.

std::pair.Respuestas:
std::initializer_listno está destinado a ser almacenado, solo está destinado a ... bien la inicialización. Internamente solo almacena un puntero al primer elemento y el tamaño. En su código, losstd::stringobjetos son temporales yinitializer_listninguno de ellos toma posesión de ellos, ni extiende su vida, ni los copia (porque no es un contenedor), por lo que quedan fuera del alcance inmediatamente después de la creación, peroinitializer_listaún tiene un puntero hacia ellos. Es por eso que tienes una falla de segmentación.Para almacenar debe usar un contenedor, como
std::vectorostd::array.fuente
initializer_list. No es posible usar objetos de solo movimiento, por lo que no puede usar list init con el vector de unique_ptr por ejemplo. El tamaño deinitializer_listno es una constante de tiempo de compilación. Y el hecho de questd::vector<int>(3)ystd::vector<int>{3}hacer cosas completamente diferentes. MeSolo agregaría un poco más de detalles. Una serie subyacente de
std::initializer_listcomportamientos de forma similar a los temporales. Considere la siguiente clase:y su uso en el siguiente código:
Se imprime
dado que en la primera línea,
Xse crea una instancia temporal de tipo (al convertir el constructor de1) y también se destruye. La referencia almacenadapentonces está colgando.En cuanto a
std::initializer_list, si lo usa de esta manera:entonces, la matriz subyacente (temporal) existe mientras exista
l. Por lo tanto, la salida es:Sin embargo, si cambia a
La salida es de nuevo
ya que la matriz subyacente (temporal) existe solo en la primera línea. Desreferenciar el puntero a los elementos de
lentonces resulta en un comportamiento indefinido.La demostración en vivo está aquí .
fuente