"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Quand la liste d'initialisation du type d'agrégat C ++ nécessite-t-elle des accolades externes?

Quand la liste d'initialisation du type d'agrégat C ++ nécessite-t-elle des accolades externes?

Publié le 2025-04-14
Parcourir:907

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

Confusion sur l'omission des accolades externes dans les listes d'initialisateur pour les agrégats et les structures de pod

Dans le domaine de la programmation C, une question commune se pose concernant l'utilisation des accessions dans les listes d'initialisateur. Plus précisément, les programmeurs peuvent rencontrer des scénarios où les accolades externes semblent être nécessaires pour certains types d'agrégats mais pas pour d'autres. Cet article vise à approfondir le sujet et à apporter des éclaircissements sur le moment où les accolades externes peuvent être omises.

Le problème

Lors de la compilation du code suivant dans Visual C 2010, un message d'erreur est généré:

struct A
{
    int foo;
    double bar;
};

std::array a1 = 
  // error C2078: too many initializers
  {
    {0, 0.1},
    {2, 3.4}
  };

// OK
std::array a2 = {0.1, 2.3};

L'erreur indique qu'il y a trop d'initialiseurs pour A1, ce qui suggère que les accolades supplémentaires sont nécessaires. Cependant, l'omission des accolades externes pour A2 n'entraîne pas une erreur. Cet écart soulève la question de savoir pourquoi les accolades externes sont nécessaires pour A1 mais pas pour a2.

L'explication

La clé pour comprendre la raison de cette différence réside dans la nature de STD :: Array. STD :: Array est classé comme un agrégat et un ancien type de données (POD), contrairement aux autres conteneurs de bibliothèque standard. Contrairement aux conteneurs avec des constructeurs définis par l'utilisateur, STD :: Array n'en a pas. Son premier membre de données est un tableau de taille n, spécifié comme argument de modèle. Ce membre de données est directement initialisé à l'aide d'une liste d'initialisateur. Les accolades supplémentaires sont nécessaires car ils enferment le tableau interne qui est en cours d'initialisation. struct aarray { Une données [2]; // un tableau interne };

L'initialisation de cette structure nécessite que l'utilisation des accolades indique le début et la fin du tableau interne en cours d'initialisation:

// Custom aggregate with no user-defined constructor
struct Aarray
{
   A data[2];  // An internal array
};

Le cas de double
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
};

dans le cas de std :: array , la situation est différente car le double n'est pas un type agrégé. Au lieu de cela, STD :: Array est considéré comme un agrégat de primitives. The following code is valid without outer braces because the primitive values ​​are directly initialized within the aggregate:std::array a2 = {0.1, 2.3};

Clarification on Brace Usage
std::array a2 = {0.1, 2.3};

The C standard provides guidelines regarding the use of braces in initializer lists. La section §8.5.1 / 11 de la spécification C 11 indique que si la liste d'initialisateur commence par une attelle gauche, chaque liste suivante de la virgule des virages d'initialiseur initialise les membres d'un sous-agrégat. D'un autre côté, si la liste d'initialisateur pour un sous-agricate ne commence pas par une attelle gauche, alors seulement suffisamment de clauses d'initialisateur pour initialiser les membres de l'agrégation. Pour les agrégats et les structures de pod, tels que STD :: Array, car ces types n'ont pas de constructeurs définis par l'utilisateur et le tableau interne est directement initialisé. Pour les types primitifs, en revanche, les accolades externes peuvent être omises car les valeurs primitives sont directement initialisées dans l'agrégat. En comprenant la différence entre ces cas, les programmeurs peuvent assurer une initialisation correcte et éviter les erreurs du compilateur.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3