Ответ 1
Это ошибка gcc, это все еще строит даже с -pedantic, в котором мы должны получать предупреждения для любых расширений
... чтобы получить все диагностические данные, требуемые стандартом, вы также должны указать -pedantic...
и gcc утверждает, что поддерживает P0329R4: Designated initializers
предложение P0329R4: Designated initializers
для C++2a
соответствии с C++ Поддержка стандартов на странице GCC:
Язык | Предложение | Доступно в GCC?
...
Назначенные инициализаторы | P0329R4 | 8
Чтобы использовать назначенные инициализаторы, тип должен быть агрегирован [dcl.init.list] p3.1:
Если список braced-init содержит список назначенных инициализаторов, T должен быть агрегатным классом. Упорядоченные идентификаторы в указателях списка назначенных-инициализаторов формируют подпоследовательность упорядоченных идентификаторов в прямых нестатических элементах данных T. Выполняется инициализация агрегата (11.6.1). [ Пример:
struct A { int x; int y; int z; }; A a{.y = 2, .x = 1}; // error: designator order does not match declaration order A b{.x = 1, .z = 2}; // OK, b.y initialized to 0
-End пример]
CC
не является агрегатом в соответствии с [dcl.init.aggr]:
Агрегатом является массив или класс (раздел 12) с
- (1.1) - нет пользовательских, явных или унаследованных конструкторов (15.1),
...
Сообщение об ошибке gcc
Если мы посмотрим на отчет gcc bug: неверное разрешение перегрузки при использовании назначенных инициализаторов мы видим в данном примере:
Другой тестовый пример, сокращенный от Chromium 70.0.3538.9 и принятый clang:
struct S { void *a; int b; }; void f(S); void g() { f({.b = 1}); }
Это не с
bug.cc: In function ‘void g(): bug.cc:3:24: error: could not convert ‘{1} from ‘<brace-enclosed initializer list> to ‘S void g() { f({.b = 1}); } ^
Ошибка указывает на то, что имена полей просто игнорируются полностью во время разрешения перегрузки, что также объясняет поведение исходного кода.
Кажется, gcc игнорирует имена полей во время разрешения перегрузки. Что объясняет странное поведение, которое вы видите, и что мы получаем правильную диагностику при удалении конструктора.