Ответ 1
Я думаю, что это gcc-ошибка (представленная как 80804). Порядок правил для [dcl.init] в С++ 17:
Если тип назначения является классом класса (возможно, cv-qualit):
- Если выражение инициализатора является prvalue, а cv-неквалифицированная версия типа источника является тем же классом, что и класс назначения, выражение инициализатора используется для инициализации целевого объекта.
Эта первая пуля не применяется. Выражение инициализатора здесь {}
, что даже не является выражением, поэтому у него даже нет cv-неквалифицированного типа для сравнения с S
. Эта пуля будет применяться, если бы мы написали S x(S{})
.
- В противном случае, если инициализация является прямой инициализацией или если она является копией-инициализацией, где cv-неквалифицированная версия типа источника является тем же классом, что или производным классом класса назначения, то конструкторы считается. Соответствующие конструкторы перечислены ([over.match.ctor]), а лучший выбирается с помощью разрешения перегрузки. Выбранный таким образом конструктор вызывается для инициализации объекта с выражением инициализатора или списком выражений в качестве аргумента (ов). Если конструктор не применяется или разрешение перегрузки неоднозначно, инициализация плохо сформирована.
Это прямая инициализация, поэтому конструкторы рассматриваются как [над .match.ctor], что просто говорит о перегрузке конструкторов. Поскольку существует конструктор std::initializer_list
, он получает приоритет на [over.ics.rank], так что он выбран.
Единственное различие между С++ 14 и С++ 17 здесь - введение этой первой пули, которая в любом случае не применяется, поэтому поведение должно быть одинаковым.