Verwirrung über das Weglassen äußerer Klammern in Initialisierungslisten für Aggregate und POD-Strukturen
Im Bereich der C-Programmierung stellt sich häufig die Frage Verwendung von geschweiften Klammern in Initialisierungslisten. Insbesondere können Programmierer auf Szenarien stoßen, in denen äußere geschweifte Klammern für bestimmte Aggregattypen erforderlich zu sein scheinen, für andere jedoch nicht. Dieser Artikel soll tiefer in das Thema eintauchen und klären, wann äußere Klammern weggelassen werden können.
Das Problem
Beim Kompilieren des folgenden Codes in Visual C 2010 Es wird eine Fehlermeldung generiert:
struct A { int foo; double bar; }; std::array<A, 2> a1 = // error C2078: too many initializers { {0, 0.1}, {2, 3.4} }; // OK std::array<double, 2> a2 = {0.1, 2.3};
Der Fehler weist darauf hin, dass zu viele Initialisierer für a1 vorhanden sind, was darauf hindeutet Die zusätzlichen Klammern sind erforderlich. Das Weglassen der äußeren Klammern für a2 führt jedoch nicht zu einem Fehler. Diese Diskrepanz wirft die Frage auf, warum für a1 äußere Klammern benötigt werden, für a2 jedoch nicht.
Die Erklärung
Der Schlüssel zum Verständnis des Grundes für diesen Unterschied liegt in der Art von std::array. std::array wird als Aggregat und als Plain Old Datatype (POD) klassifiziert, andere Standardbibliothekscontainer dagegen nicht. Im Gegensatz zu Containern mit benutzerdefinierten Konstruktoren verfügt std::array nicht über einen. Sein erstes Datenelement ist ein Array der Größe N, das als Vorlagenargument angegeben wird. Dieses Datenelement wird direkt mithilfe einer Initialisierungsliste initialisiert. Die zusätzlichen geschweiften Klammern sind erforderlich, da sie das interne Array einschließen, das initialisiert wird.
Um dieses Konzept weiter zu veranschaulichen, betrachten Sie einen benutzerdefinierten Aggregattyp Aarray, der wie folgt definiert ist:
// Custom aggregate with no user-defined constructor struct Aarray { A data[2]; // An internal array };
Dies wird initialisiert Die Struktur erfordert die Verwendung von geschweiften Klammern, um den Anfang und das Ende des zu initialisierenden internen Arrays zu kennzeichnen:
Aarray a1 = { { // Begins initialization of the internal array { // Initializes the first element of the internal array 0, 0.1 }, // Ends initialization of the first element {2, 3.4} // Initializes the second element of the internal array } // Ends initialization of the internal array }; // ERROR: Too many initializers if not using braces Aarray b1 = { 0, 0.1, 2, 3.4 };
Der Fall von Double
Im Fall von std::array
std::array<double, 2> a2 = {0.1, 2.3};
Klarstellung zur Verwendung von Klammern
Der C-Standard enthält Richtlinien dazu die Verwendung von geschweiften Klammern in Initialisierungslisten. Abschnitt §8.5.1/11 der C 11-Spezifikation besagt, dass, wenn die Initialisierungsliste mit einer linken Klammer beginnt, jede nachfolgende durch Kommas getrennte Liste von Initialisierungsklauseln die Mitglieder eines Unteraggregats initialisiert. Wenn andererseits die Initialisierungsliste für ein Unteraggregat nicht mit einer linken Klammer beginnt, werden nur genügend Initialisierungsklauseln verwendet, um die Unteraggregatmitglieder zu initialisieren, wobei alle verbleibenden Initialisierungsklauseln das nächste Aggregatmitglied initialisieren.
Fazit
Die Verwendung äußerer Klammern in Initialisierungslisten ist für Aggregate und POD-Strukturen wie std::array von entscheidender Bedeutung, da diese Typen keine benutzerdefinierten Konstruktoren haben und das interne Array direkt initialisiert wird. Bei primitiven Typen hingegen können äußere Klammern weggelassen werden, da die primitiven Werte direkt innerhalb des Aggregats initialisiert werden. Durch das Verständnis des Unterschieds zwischen diesen Fällen können Programmierer eine korrekte Initialisierung sicherstellen und Compilerfehler vermeiden.
Das obige ist der detaillierte Inhalt vonWann sind äußere Klammern in C-Initialisierungslisten für Aggregate erforderlich?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!