Равномерная инициализация и std::initializer_list
Я изучаю C++ и дошел до того, что читаю об инициализации списка. После некоторой путаницы, из-за перекрытия синтаксиса, я понял, что равномерная инициализация и инициализация списка действительно две разные (хотя я только что сказал, перекрытия) новые возможности C++11. Поэтому, прежде чем я задам свой вопрос, я хотел бы повторить, и, пожалуйста, поправьте меня, если я что-то не так (до того, как что-то станет заблуждением по этой теме..)
Что касается встроенных типов, то синтаксис для их инициализации выглядит следующим образом (я предполагаю int для удобства чтения):
// defines a default initialized int
int a;
// defines a value initialized int (binary zeroes)
int a{};
// equivalent definitions,define an int variable of value 10:
int a=10;
int a(10);
int a{10};
int a={10};
// equivalent definitions,define a temporary int variable of value 10:
int(10);
int{10};
// equivalent definitions,define a temporary int variable that is value initialized to 0:
int();
int{};
Теперь перейдем к интересной части, используя единую инициализацию для типов агрегатов (массивов и структур агрегатов). До C++ 11 я мог инициализировать массивы и массивы с помощью инициализатора списка:
int array[]={1,2,3};
struct aggregate {
int a;
double b;
};
aggregate a={1,2.3};
теперь я знаю, что новый стандарт позволяет мне использовать новый синтаксис для унифицированной инициализации:
int array[]{1,2,3};
aggregate a{1,2,3};
это может пригодиться для использования в списках инициализации членов конструктора.
а теперь к классам типов. Если класс не определяет конструктор initializers_list:
// equivalent definitions,define a class_type variable,default initialized:
class_type name;
class_type name{};
// equivalent definitions,define a class_type variable,using the appropriate constructor:
class_type name(*args*);
class_type name{*args*};
class_type name={*args*};
// defines a class_type variable and calls copy-constructor (allows implicit conversion to class_type if converting constructor is non-explicit)
class_type name=name2;
// equivalent definitions,define a temporary class_type object,default initialized
class_type();
class_type{};
// equivalent definitions,define a temporary class_type object,initialized by the appropriate constructor
class_type(*args*);
class_type{*args*};
Я знаю, что когда класс определяет конструктор class_type::class_type(const std::initializer_list&), он имеет приоритет над другими конструкторами (если только это не пустой список, а конструктор по умолчанию имеет приоритет).
Теперь мой вопрос:
что это =
изменить, когда я использую его со списком скобок? Единственное различие, о котором я мог подумать, заключается в том, является ли конструктор списка инициализации явным или нет.
class_type name{*args*};
class_type name={*args*};
такой же как
class_type name({*args*});
class_type name=class_type(std::initializer_list({*args*}));
и так инициализация копирования неявного преобразования участвует? это единственная разница?
Пожалуйста, поправьте меня, если я говорю что-то явно неправильно!