«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Когда в списке инициализации типа агрегата C ++ требуется внешние скобки?

Когда в списке инициализации типа агрегата C ++ требуется внешние скобки?

Опубликовано в 2025-04-14
Просматривать:566

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

путаница из -за пропущения внешних скоб в списках инициализатора для агрегатов и структур POD

В сфере программирования C, возникает общий вопрос, касающийся использования скоб в списках инициализатора. В частности, программисты могут столкнуться с сценариями, в которых внешние скобки, по -видимому, требуются для определенных типов агрегатов, но не для других. Эта статья направлена ​​на то, чтобы глубже углубиться в тему и дать разъяснения о том, когда внешние скобки могут быть опущены. { int foo; двойной батончик; }; std :: array a1 = // ошибка C2078: слишком много инициализаторов { {0, 0,1}, {2, 3.4} }; // ХОРОШО std :: array a2 = {0.1, 2,3};

ошибка указывает на то, что для A1 слишком много инициализаторов, предполагая, что требуются дополнительные скобки. Тем не менее, пропущение внешних скобков для A2 не приводит к ошибке. Это несоответствие поднимает вопрос о том, почему внешние скобки необходимы для A1, но не для A2.

объяснение

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};
]

, чтобы еще больше проиллюстрировать эту концепцию, рассмотрим пользовательский тип агрегата, определяемый следующим образом:

// Пользовательский агрегат без определенного пользователя конструктора Структура Ааррея { Данные [2]; // внутренний массив }; инициализация этой структуры требует использования скобков для обозначения начала и конца инициализированного внутреннего массива:

aarray a1 = { {// начинает инициализацию внутренней массивы {// инициализирует первый элемент внутреннего массива 0, 0,1 }, // заканчивается инициализация первого элемента {2, 3.4} // Инициализирует второй элемент внутреннего массива } // заканчивает инициализацию внутренней массивы }; // ошибка: слишком много инициализаторов, если не используют бреконы Aarray B1 = { 0, 0,1, 2, 3.4 };

случай double
// Custom aggregate with no user-defined constructor
struct Aarray
{
   A data[2];  // An internal array
};

в случае std :: array , ситуация отличается, потому что двойной не является агрегатным типом. Вместо этого std :: массив считается совокупностью примитивов. Следующий код действителен без внешних скоб, потому что примитивные значения непосредственно инициализируются в агрегате:

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
};

уточнение на использовании BRACE

CNTRAND DIGENINES, рассматривающие BRACES, в соответствии с использованием BRACESISER. Раздел §8.5.1/11 спецификации C 11 гласит, что если список инициализатора начинается с левой скобы, то каждый последующий список, разделенные запятыми, инициализирует членов субаггрегата. С другой стороны, если список инициализатора для субагрегата не начинается с левой скобы, то будет принято только достаточное количество инициализирующих-инициализируемые члены агрегата. Агрегаты и структуры стручков, такие как std :: массив, потому что эти типы не имеют определенных пользовательских конструкторов, а внутренний массив напрямую инициализируется. Для примитивных типов, с другой стороны, внешние скобки могут быть пропущены, поскольку примитивные значения непосредственно инициализируются в рамках заполнителя. Понимая разницу между этими случаями, программисты могут обеспечить правильную инициализацию и избежать ошибок компилятора.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3