Dieser Code:
#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;
}
Kompiliert, gibt aber segfault zurück. Warum?
Getestet auf gcc 8.3.0 und auf Online-Compilern.
std::pair
.Antworten:
std::initializer_list
ist nicht zum Speichern gedacht, sondern nur zum ... gut Initialisieren. Intern wird nur ein Zeiger auf das erste Element und die Größe gespeichert. In Ihrem Code sind diestd::string
Objekte temporär undinitializer_list
keiner übernimmt das Eigentum an ihnen, verlängert weder ihre Lebensdauer noch kopiert er sie (weil es sich nicht um einen Container handelt), sodass sie unmittelbar nach der Erstellung den Gültigkeitsbereich verlassen, aber Sie habeninitializer_list
immer noch einen Zeiger auf sie. Deshalb erhalten Sie einen Segmentierungsfehler.Zum Aufbewahren sollten Sie einen Behälter wie
std::vector
oder verwendenstd::array
.quelle
initializer_list
. Es ist nicht möglich, nur Verschiebungsobjekte zu verwenden, daher können Sie beispielsweise list init mit dem Vektor unique_ptr nicht verwenden. Die Größe voninitializer_list
ist keine Kompilierungszeitkonstante. Und die Tatsache, dassstd::vector<int>(3)
undstd::vector<int>{3}
ganz andere Dinge tun. Macht mich traurig :(Ich würde nur ein bisschen mehr Details hinzufügen. Ein zugrunde liegendes Array von
std::initializer_list
Verhaltensweisen verhält sich ähnlich wie temporäre. Betrachten Sie die folgende Klasse:und seine Verwendung im folgenden Code:
Es wird ausgedruckt
da in der ersten Zeile eine temporäre Instanz des Typs
X
erstellt (durch Konvertieren des Konstruktors von1
) und ebenfalls zerstört wird. Die darin gespeicherte Referenzp
baumelt dann.Was
std::initializer_list
, wenn Sie es auf diese Weise verwendet werden :Dann existiert das zugrunde liegende (temporäre) Array, solange es beendet wird
l
. Daher lautet die Ausgabe:Wenn Sie jedoch zu wechseln
Die Ausgabe ist wieder
da das zugrunde liegende (temporäre) Array nur in der ersten Zeile vorhanden ist. Das Dereferenzieren des Zeigers auf die Elemente von
l
führt zu einem undefinierten Verhalten.Live-Demo ist da .
quelle