Heim > Backend-Entwicklung > C++ > Wann sind äußere Klammern in C-Initialisierungslisten für Aggregate erforderlich?

Wann sind äußere Klammern in C-Initialisierungslisten für Aggregate erforderlich?

Patricia Arquette
Freigeben: 2024-12-08 12:48:12
Original
454 Leute haben es durchsucht

When are Outer Braces Necessary in C   Initializer Lists for Aggregates?

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};
Nach dem Login kopieren

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
};
Nach dem Login kopieren

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
};
Nach dem Login kopieren

Der Fall von Double

Im Fall von std::array ist die Situation anders, da double kein Aggregattyp ist. Stattdessen std::array wird als eine Ansammlung von Primitiven betrachtet. Der folgende Code ist ohne äußere Klammern gültig, da die Grundwerte direkt innerhalb des Aggregats initialisiert werden:

std::array<double, 2> a2 = {0.1, 2.3};
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage