Ответ 1
Разрешение перегрузки это весело.
-
{a}
имеет точный ранг соответствия для инициализации (временного значения) параметраconst A&
, который превосходит пользовательское преобразованиеB(const A&)
как реализацию{a}
. Это правило было добавлено в С++ 14 для устранения неоднозначностей при инициализации списка (наряду с корректировками для агрегатов).Обратите внимание, что условное временное значение никогда не создается: после выбора разрешения перегрузки
f(const A&)
ссылка просто инициализируется для ссылки наa
, и эта интерпретация может применяться даже для не копируемых типов. - Было бы допустимо инициализировать
const A&
параметрconst A&
(как указано выше) конструктору дляA
илиB
, поэтому вызов является неоднозначным. - Повторный вызов конструктора копирования (здесь
A(const A&)
) запрещен как несколько пользовательских преобразований, а не разрешает одно такое преобразование на уровень разрешения перегрузки. Поэтому внешние скобки должны инициализироватьB
изA
инициализированного из{{a}}
как (разрешено) во втором случае. (Средний слой фигурных скобок может инициализироватьB
, но копирование его с внешним слоем будет запрещено, и больше ничего не нужно пытаться инициализировать.) - Каждая интерпретация включает в себя такое запрещенное дополнительное обращение.
Отсутствие скобки - мы не знаем, какой внешний тип цели позволяет это сделать.