Условный оператор проверяет преобразования в обоих направлениях.В этом случае, поскольку ваш конструктор является явным (поэтому ?:
не является неоднозначным), используется преобразование из Foo
в int
с использованием функции преобразования, которая преобразуется в double
: это работает, потому что после примененияза функцией преобразования следует стандартное преобразование, которое преобразует double
в int
(усечение).Результат ?:
в вашем случае равен int
и имеет значение 6
.
Во втором случае, поскольку операнд имеет тип double
, такого конечного преобразования в int
не происходит, и, таким образом, тип результата ?:
имеет тип double
с ожидаемым значением.
Чтобы понять «ненужные» преобразования, вы должны понимать, что выражения, подобные вашему ?:
, оцениваются как «не зависящие от контекста»: при определении значения и его типа компилятор не считает, что оноперанд return
для функции, возвращающей double
.
Редактировать: Что произойдет, если ваш конструктор неявный ?Выражение ?:
будет неоднозначным, поскольку вы можете преобразовать int
в значение типа Foo
(с помощью конструктора) и Foo
в значение типа int
(с помощью функции преобразования).,Стандарт гласит:
. Используя этот процесс, определяется, может ли второй операнд быть преобразован, чтобы соответствовать третьему операнду, и может ли третий операнд быть преобразован, чтобы соответствовать второму операнду.Если оба могут быть преобразованы, или один может быть преобразован, но преобразование неоднозначно, программа имеет неправильную форму.
Параграфы, объясняющие, как ваш Foo
преобразуется в int
:
5.16/3
about condition ? E1 : E2
:
В противном случае, если второй и третий операнды имеют разные типы и имеют либо (возможно, cv-квалифицированный) тип класса, попыткасделано для преобразования каждого из этих операндов в тип другого.[...] E1 может быть преобразован в соответствие E2, если E1 может быть неявно преобразован в тип, который будет иметь выражение E2, если E2 будет преобразовано в значение r (или тип, который он имеет, если E2 является значением r).
4.3
о «неявно преобразованном»:
Выражение e может быть неявно преобразовано в тип T тогда и только тогда, когда объявление T t = e;
правильно сформировано, длянекоторая изобретенная временная переменная t.
8.5/14
о инициализации копирования (T t = e;
)
Если тип источника является (возможно, cv-квалифицированным) типом класса,функции преобразования рассматриваются.Перечислены применимые функции преобразования (13.3.1.5), и лучшая из них выбирается с помощью разрешения перегрузки (13.3).Выбранное пользователем преобразование, выбранное таким образом, вызывается для преобразования выражения инициализатора в инициализируемый объект.Если преобразование не может быть выполнено или является неоднозначным, инициализация является неправильной.
13.3.1.5
о кандидатах на функцию преобразования
Функции преобразования S и егобазовые классы считаются.Те, которые не скрыты в S и дают тип T или тип, который можно преобразовать в тип T с помощью стандартной последовательности преобразования (13.3.3.1.1), являются функциями-кандидатами.