Теперь у нас есть пяти форм инициализации. Итог:
T x = expression;
T x = (expression);
T x ( expression);
T x = { expression };
T x { expression };
Каждая из форм имеет свои особенности. :)
Например, давайте предположим, что у вас есть следующие объявления в глобальном пространстве имен
int x;
void f(int x) { ::x = x; }
int g() { return x ; }
long h() { return x; }
затем в основной вы можете написать
int main()
{
int x (g());
}
Этот код компилируется успешно.
Однако программист по ошибке сделал опечатку
int main()
{
int x; (g());
^^
}
Oops! Этот код также компилируется успешно. :)
Но если программист напишет
int main()
{
int x = (g());
}
, а затем сделать опечатку
int main()
{
int x; = (g());
^^
}
, то в этом случае код не будет компилироваться.
Предположим, что программист решил сначала установить новое значение для global variabel x перед инициализацией локальной переменной.
Так он писал
int main()
{
int x (f(10), g());
}
Но этот код не компилируется!
Пусть; s вставить знак равенства
int main()
{
int x = (f(10), g());
}
Теперь код успешно компилируется!
А как насчет брекетов?
Ни этот код
int main()
{
int x { f(10), g() };
}
ни этот код
int main()
{
int x = { f(10), g() };
}
компилирует! :)
Теперь программист решил использовать функцию Н(), он писал
int main()
{
int x (h());
}
и его код успешно компилируется. Но через какое-то время он решил использовать брекеты
int main()
{
int x { h() };
}
Упс! Его компилятор выдает сообщение об ошибке
error: non-constant-expression cannot be narrowed from type 'long' to 'int' in initializer list
Программа решила использовать спецификатор типа auto. Он попробовал два подхода
int main()
{
auto x { 10 };
x = 20;
}
и
int main()
{
auto x = { 10 };
x = 20;
}
и ... некоторые компиляторы составил первую программу, но не собрали вторую программу и некоторые компиляторы не компилировать обе программы. :)
А как насчет использования decltype
?
Например, программист написал
int main()
{
int a[] = { 1, 2 };
decltype(auto) b = a;
}
И его компилятор выдал ошибку!
Но когда программист приложена в скобках, как этот
int main()
{
int a[] = { 1, 2 };
decltype(auto) b = (a);
}
код компилируется успешно! :)
Теперь программист решил узнать ООП. Он написал простой класс
struct Int
{
Int(int x = 0) : x(x) {}
int x;
};
int main()
{
Int x = { 10 };
}
и его код успешно скомпилирован. Но pogrammer уже известно, что существует функция спецификатор explicit
и он решил использовать его
struct Int
{
explicit Int(int x = 0) : x(x) {}
int x;
};
int main()
{
Int x = { 10 };
}
Oops! Его компилятор выдал ошибку
error: chosen constructor is explicit in copy-initialization
Программист решил удалить знак присваивания
struct Int
{
explicit Int(int x = 0) : x(x) {}
int x;
};
int main()
{
Int x { 10 };
}
и его код, скомпилированный успешно! :)
Таким образом, в данном случае, это не имеет значения, что мы используем ? Хотя в тех случаях, когда мы делаем много времени для int или когда есть вероятность потери данных, он должен вызывать исключение/ошибку? –
@cruskal, если '==' перегружен, чтобы возвращать что-то другое, кроме 'bool',' {} 'генерирует ошибку. –
Кроме того, остерегайтесь сочетания инициализаторов, сопоставленных с 'std :: initializer_list' в конструкторах, например' std :: vector c {a, b} 'vs' std :: vector c (a, b) ' –