В C ++ 11 введены инициализации в стиле {}. Но эти две формы
T x {...};
T x = {...};
тот же самый?
Они не совсем одинаковые. Может быть, это можно проиллюстрировать контрпримером:
struct Foo
{
explicit Foo(std::initializer_list<int>) {}
};
int main()
{
Foo f0{1, 2, 3}; // OK
Foo f1 = {1, 2, 3}; // ERROR
}
Таким образом, второй вариант требует, чтобы тип неявно создавался из списка инициализации, тогда как первая версия этого не делает. Обратите внимание, что то же самое относится к конструкторам вида Foo(int, int, int)
, Я выбрал initializer_list<int>
в качестве примера произвольно.
Это повлияет на определенные типы, написанные в соответствии с философией «явного повсюду» (когда люди отмечают многопараметрические конструкторы explicit
в коде C ++ 03, даже если в этом стандарте это не имело смысла.)
В дополнение к разнице, объясненной в Juanchopanza’s ответ, есть еще одно различие, переломное изменение, между прямой список инициализация а также копирование списка инициализация когда дело доходит до auto
и тип вычета приготовился-INIT-лист. Хотя это было не добавлено как часть C ++ 14 (последний вопрос&Пункт), проблема была определена, и это до комитета, когда это будет выполнено.
Например,
auto foo = {42}; // deduces foo as an initializer_list<int>
auto foo{42}; // deduces foo as an int
Таким образом, прямая инициализация списка никогда не выводит initializer_list
из аргумента. Следовательно, следующее будет плохо сформировано.
auto foo{1,2}; // cannot have multiple initializers for
// direct-list-initialization when deducing type
Но это нормально
auto foo = {1,2}; // copy-list-initialization still deduces initializer_list<int>
То же самое относится и к обобщенным захватам в лямбда-выражениях. квотирование N3912
[x{5}](){}; // x is int
[x{1,2}](){}; // ill-formed, no multiple initializers with direct-init
[x = {5}](){}; // ok, x is an initializer_list<int> with one element
[x = {1,2}](){}; // ok, x is an initializer_list<int> with two elements
синтаксис при их использовании в одном случае подразумеваются разные вещи
struct A { };
namespace X {
struct A final {};
struct A final = {};
}
В первом случае мы определяем структуру под названием A
и во втором случае мы определяем объект с именем final
,