Неявно созданный конструктор списка инициализаторов

В С ++ стандарт для std::array это говорит:

Массив - это агрегат (8.5.1), который можно инициализировать с помощью синтаксиса

массив a = { initializer-list };

где initializer-list - разделенный запятыми список до N элементов, типы которых могут быть преобразованы в T.

Также это говорит о том, что std::array является агрегатным типом, и его конструкторы неявно генерируются.

Для инициализации std::array со списком инициализатора он должен иметь конструктор, принимающий std::initializer_list в качестве аргумента.

Является ли конструктор, который принимает std::initializer_list также неявно генерируется для пользовательских типов или это специфично для std::array?

3 ответа

Решение

Редактировать:

Синтаксис работает для агрегатных типов,

#include <iostream>
using namespace std;

struct A {
    int a;
    int b;
    int get_a() {return a;}
};

int main() {
    A a1({4,5});
    A a2{1,2};
    cout << a1.a << '\n';
    cout << a2.b << '\n';
    return 0;
}

Жить

Но технически для агрегатных типов конструктор не создается. Эти вызовы представляют две формы инициализации списка. поскольку T является агрегатом, он относится к маркеру, связанному с инициализацией агрегата.

Нет, компилятор не генерирует конструктор, принимающий std::initializer_listни для std::array ни для любого другого агрегатного типа.

То, что вы наблюдаете здесь, является совокупной инициализацией, которая совершенно не связана с std::initializer_list,

Термин "список инициализаторов" в предоставленном вами стандартном фрагменте относится к списку инициализаторов, который опять-таки не имеет ничего общего с std::initializer_list,

Вы можете проверить это примерно так:

struct A {
    int i;
    std::string str;
};

int main() {
    A a{1, "asdf"};
}

Это работает, но явно не использует std::initializer_list так как это может обрабатывать только один тип одновременно.

std::array is aggregate and so aggregate-initialization is used, and no constructor that receives std::initializer_list is generated.

Если инициализатором является (не заключенный в скобки) фигурный список инициализации, объект или ссылка инициализируются списком (8.5.4).

List-initialization is initialization of an object or reference from a braced-init-list. Such an initializer is called an initializer list, and the comma-separated initializer-clauses of the list are called the elements of the initializer list.

Инициализация списка объекта или ссылки типа T is defined as follows:

Если T является агрегатом, выполняется агрегатная инициализация (8.5.1).

Когда агрегат инициализируется списком инициализаторов, как указано в 8.5.4, элементы списка инициализаторов берутся в качестве инициализаторов для элементов агрегата в порядке возрастания индекса или элемента. Each member is copy-initialized from the corresponding initializer-clause.

Другие вопросы по тегам