Maison > développement back-end > C++ > Quand les accolades externes sont-elles nécessaires dans les listes d'initialisation C pour les agrégats ?

Quand les accolades externes sont-elles nécessaires dans les listes d'initialisation C pour les agrégats ?

Patricia Arquette
Libérer: 2024-12-08 12:48:12
original
453 Les gens l'ont consulté

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

Confusion concernant l'omission des accolades externes dans les listes d'initialisation pour les agrégats et les structures POD

Dans le domaine de la programmation C, une question courante se pose concernant le utilisation d'accolades dans les listes d'initialisation. Plus précisément, les programmeurs peuvent rencontrer des scénarios dans lesquels des accolades externes semblent être requises pour certains types d'agrégats mais pas pour d'autres. Cet article vise à approfondir le sujet et à fournir des éclaircissements sur les cas 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<A, 2> a1 = 
  // error C2078: too many initializers
  {
    {0, 0.1},
    {2, 3.4}
  };

// OK
std::array<double, 2> a2 = {0.1, 2.3};
Copier après la connexion

L'erreur indique qu'il y a trop d'initialiseurs pour a1, suggérant que les accolades supplémentaires sont nécessaires. Cependant, l’omission des accolades extérieures pour a2 n’entraîne pas d’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 derrière cette différence réside dans le nature de std::array. std::array est classé comme un agrégat et un Plain Old Datatype (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’initialisation. Les accolades supplémentaires sont nécessaires car elles entourent le tableau interne en cours d'initialisation.

Pour illustrer davantage ce concept, considérons un type d'agrégat personnalisé Aarray, défini comme suit :

// Custom aggregate with no user-defined constructor
struct Aarray
{
   A data[2];  // An internal array
};
Copier après la connexion

Initialisation de ceci La structure nécessite l'utilisation d'accolades pour désigner le début et la fin du tableau interne en cours d'initialisation :

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
};
Copier après la connexion

Le cas de Double

Dans le cas de std::array, la situation est différente car double n'est pas un type d'agrégat. Au lieu de cela, std::array est considéré comme un agrégat de primitives. Le code suivant est valide sans accolades externes car les valeurs primitives sont directement initialisées dans l'agrégat :

std::array<double, 2> a2 = {0.1, 2.3};
Copier après la connexion

Clarification sur l'utilisation des accolades

La norme C fournit des lignes directrices concernant l'utilisation d'accolades dans les listes d'initialisation. La section §8.5.1/11 de la spécification C 11 indique que si la liste d'initialisation commence par une accolade gauche, alors chaque liste suivante de clauses d'initialisation séparées par des virgules initialise les membres d'un sous-agrégat. D'un autre côté, si la liste d'initialisation d'un sous-agrégat ne commence pas par une accolade gauche, alors seulement suffisamment de clauses d'initialisation seront prises pour initialiser les membres du sous-agrégat, toutes les clauses d'initialisation restantes initialisant le membre d'agrégat suivant.

Conclusion

L'utilisation d'accolades externes dans les listes d'initialisation est cruciale pour les agrégats et les structures POD, telles que std::array, car ces types n'ont pas de constructeurs définis par l'utilisateur et le tableau interne est directement initialisé. En revanche, pour les types primitifs, 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 garantir une initialisation correcte et éviter les erreurs du compilateur.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal