Clang прав, отвергнув его, и это действительно ошибка GCC.Я процитирую n4659 (ближайший документ, который мне нужен к стандарту C ++ 17) для простоты.
Прежде всего, тип условного выражения в вашем примере, как указано [expr.cond] ¶6 должен быть prvalue типа A
.
Теперь, согласно [expr.cond] ¶7 , выделение мое:
Стандартные преобразования Lvalue-to-rvalue , массива-в-указатель и функции-в-указатель выполняются для второго и третьего операндов.
a
должен быть в состоянии пройти преобразование lvalue в rvalue.Который для a
указан в [conv.lval] .23.2 (опять же, выделено мое) как
В противном случае, если T имеет тип класса, преобразование copy-initializes результирующий объект из glvalue.
Копирование инициализации A
из A
, в любом контексте, должно выбирать конструктор преобразования в разрешении перегрузки ( [over.match.copy] ¶1.1 ):
Конвертирующие конструкторы T являются функциями-кандидатами.
И явный конструктор копирования не являетсяконструктор преобразования ( [class.conv.ctor] ¶3 )
A неявный конструктор копирования / перемещения ([class.copy])является конвертирующим конструктором.
Соответствующая реализация C ++ не может принять условное выражение, которое вы написали, как правильно сформированное.