С++ 11 представил {} -истинные инициализации. Но эти две формы
T x {...};
T x = {...};
то же самое?
С++ 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
в коде С++ 03, даже если это не имеет смысла в этом стандарте.)
В дополнение к различию, объясненному в juanchopanza answer, существует другая разница, нарушение изменения между инициализацией прямого списка и инициализацией списка копий, когда оно доходит до auto
и выводит вывод скопированного-init-списка. Хотя он был не добавлен как часть С++ 14 (последний элемент Q & A), проблема была идентифицирована, и это зависит от комитет, когда он будет реализован.
Например,
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
.