С++ Почему инициализация std::array выглядит именно так?

Есть следующий код:

#include <iostream>
#include <string>
#include <conio.h>
#include <array>

struct Student
{
    std::string m_str;
    int m_value;
};

int main()
{
    std::array<Student, 3> arr{
        {
            {"str0", 100},
            {"str1", 101},
            {"str2", 102}
        }
    };

    std::cout << arr[0].m_str << " " << arr[0].m_value << std::endl;
    std::cout << arr[1].m_str << " " << arr[1].m_value << std::endl;
    std::cout << arr[2].m_str << " " << arr[2].m_value << std::endl;

    _getch();
    return 0;
}

Пожалуйста, об'ясните, почему при инициализации arr ми используем две пары фигурных скобок (по-идее, первая пара - это uniform инициализация, а вторая?)

Если убрать одну пару, то введите сюда описание изображения

Заранее спасибо.


Ответы (2 шт):

Автор решения: user7860670

У вас на самом деле стоят аж три пары скобочек (то бишь аж три инициализатора для первого поля), хотя в такой ситуации достаточно будет только одной в которой будет заключено 2 (по одному инициализатору для каждого поля) х 3 (по количеству объектов) = 6 инициализаторов:

#include <string>
#include <array>

struct Student
{
    std::string m_str;
    int m_value;
};

std::array<Student, 3> arr
{
    "str0", 100
,   "str1", 101
,   "str2", 102
};

https://godbolt.org/z/necovG

→ Ссылка
Автор решения: HolyBlackCat

У std::array нет конструкторов (кроме сгенерированных компилятором автоматически), поэтому он инициализируется списком полей в фигурных скобках. Это называется aggregate initialization.

У него одно поле - обычный массив. Что-то в духе вот этого:

namespace std
{
    template <typename T, std::size_t N>
    struct array
    {
        T elems[N];
        // ...
    };
}

Поэтому одна пара скобок - для всего std::array, а вторая для этого внутреннего массива.

В некоторых случаях одну пару скобок можно опускать, но не здесь (точные условия см. по ссылке выше).

→ Ссылка