Ответ 1
Да:
void foo(a::really::long::type::name arg = {});
Подводя итог следующим стандартным определениям:
Это инициализация списка. В зависимости от типа выполняется инициализация агрегата или объект инициализируется значением, которое, в свою очередь, подразумевает инициализацию по умолчанию или нуль.
Некоторые "угловые" случаи - это когда тип является специализацией std::initializer_list
или когда тип имеет конструктор std::initializer_list
(он вызывается, если он не имеет конструктора по умолчанию)
Соответствующие стандартные кавычки (чтобы мы встречались с определениями):
§8.3.6 Аргументы по умолчанию [dcl.fct.default]
1 Если в объявлении параметра указано предложение initializer, это Параметр initializer используется как аргумент по умолчанию
5 Аргумент по умолчанию имеет те же семантические ограничения, что и инициализатор в объявлении переменной типа параметра, используя семантику инициализации копирования (8.5)
§8.5.4 List-initialization [dcl.init.list]
1 Инициализация списка - это инициализация объекта или ссылки из скопированного списка инициализации. Такой инициализатор называется инициализатором список, [...]. Список инициализаторов может быть пустым. Инициализация списка может происходят в контекстах с прямой инициализацией или инициализацией копии; [..] инициализация списка в контекст копирования-инициализации называется copy-list-initialization.
3 Список-инициализация объекта или ссылки типа T определяется следующим образом:
- Если T является агрегатом, выполняется инициализация (8.5.1)
- В противном случае, если в списке инициализаторов нет элементов, а T - класс type с конструктором по умолчанию, объект инициализирован значением.
- В противном случае, если T является специализацией std:: initializer_list, объект initializer_list prvalue сконструирован, как описано ниже, и используется для инициализации объекта в соответствии с правилами для инициализация объекта из класса того же типа (8.5).
- В противном случае, если T - тип класса, рассматриваются конструкторы. Соответствующие конструкторы перечислены, и лучший выбирается с помощью разрешения перегрузки (13.3, 13.3.1.7) [...]
- ...
- В противном случае, если в списке инициализаторов нет элементов, объект инициализируется значением.
§ 8.5 Инициализаторы [dcl.init]
8 Для value-initialize объект типа T означает:
- если T является (возможно, cv-квалифицированным) классом типа (раздел 9) без конструктора по умолчанию (12.1) или конструктора по умолчанию, который предоставляемый пользователем или удаленный, то объект по умолчанию инициализирован;
- если T является (возможно, cv-квалифицированным) классом без созданного пользователем или удаляемого конструктора по умолчанию, тогда объект с нулевой инициализациейи проверяются семантические ограничения для инициализации по умолчанию, и если T имеет нетривиальный конструктор по умолчанию, объект по умолчанию инициализируется
- если T - тип массива, то каждый элемент инициализируется значением;
- в противном случае объект с нулевой инициализацией
7 Для default-initialize объект типа T означает:
- если T - тип класса (возможно, cv-qualit) (раздел 9), конструктор по умолчанию (12.1) для T называется (и инициализация плохо сформированный, если T не имеет конструктора по умолчанию или разрешения перегрузки (13.3) приводит к двусмысленности или в функции, которая удалена или недоступный из контекста инициализации);
- если T - тип массива, каждый элемент по умолчанию инициализирован;
- в противном случае инициализация не выполняется.
6 Для нулевой инициализации объект или ссылка типа T означает:
- если T - скалярный тип (3.9), объект инициализируется значением, полученным преобразованием целочисленного литерала 0 (ноль) в T;
- если T является (возможно, cv-квалифицированным) классом неединичного класса, каждый нестатический член данных и каждый подобъект базового класса нулевое инициализирование и заполнение инициализируются нулевыми битами;
- если T является (возможно, cv-квалифицированным) типом объединения, объекты первого нестатического именованного элемента данных ноль инициализируются, а заполнение - инициализируется нулевыми битами;
- если T - тип массива, каждый элемент инициализируется нулем;
- если T является ссылочным типом, инициализация не выполняется.
§13.3.1.7 Инициализация с помощью инициализации списка [over.match.list]
1 Когда объекты неагрегатного типа типа T инициализируются списком (8.5.4), разрешение перегрузки выбирает конструктор в две фазы:
- Изначально функции-кандидаты являются конструкторами-конструкторами инициализатора (8.5.4) класса T, а список аргументов состоит из список инициализаторов как один аргумент.
- Если не найден жизнеспособный конструктор списка инициализаторов, снова выполняется разрешение перегрузки, где все функции-кандидаты конструкторы класса T и список аргументов состоят из элементы списка инициализаторов.
Если в списке инициализаторов нет элементов, а T имеет значение по умолчанию конструктор, первая фаза опущена. [...]