Ответ 1
Конструктор по умолчанию применим только в том случае, если вы используете одну пару обеих фигур:
auto a = Foo(); // Foo()
auto b = Foo{}; // Foo()
Foo({})
вместо этого будет вызывать только конструкторы с пустым списком в качестве аргумента, а именно - list-list - инициализирует параметр любого конструктора. [Dcl.init]/16:
Если тип назначения является (возможно, cv-qualit) типом класса:
- If инициализация - это прямая инициализация [...]. Соответствующие конструкторы перечислены (13.3.1.3), а лучший выбирается путем перегрузки резолюции (13.3). Выбранный таким образом конструктор вызывается инициализировать объект, с помощью выражения инициализатора или выражение-список как его аргумент. Если конструктор не применяется, или разрешение перегрузки неоднозначно, инициализация плохо сформирован.
У вас есть один аргумент: пустой бит-init-list. Существует последовательность инициализации списка, преобразующая {}
в int
, поэтому конструктор Foo(int)
выбирается с помощью разрешения перегрузки. Параметр инициализируется равным нулю, поскольку {}
подразумевает value-intialization, который для скаляров подразумевает нулевой инициализации.
В документации cppreferences также нет ошибки: для (7) указано, что
7) в функциональном выражении или другой прямой инициализации, с braced-init-list, используемым как аргумент конструктора
Это явно приводит к такому же результату, что и к приведенной выше цитате: конструктор вызывается с (пустым) скобками-init-list.