条件演算子は、両方向の変換をチェックします。この場合、コンストラクターは明示的であるため(したがって、?:
はあいまいではありません)、からFoo
への変換は、にint
変換する変換関数を使用して使用されますdouble
。これは、変換関数を適用した後、をに変換する標準の変換であるため、機能しdouble
ますint
。切り捨て)が続きます。?:
あなたの場合の結果はでint
あり、値はです6
。
2番目のケースでは、オペランドの型がであるdouble
ため、このような末尾の変換int
は行われず、結果の型は期待値の?:
型になります。double
「不必要な」変換を理解するには、あなたのような式が「文脈自由」で評価されることを理解する必要があります。その値とタイプを決定するとき、コンパイラはそれがaを返す関数?:
のオペランドであるとは見なしません。 。return
double
編集:コンストラクターが暗黙的である場合はどうなりますか?を型の右辺値に(コンストラクターを使用して)変換し、aを型の右辺値に(変換関数を使用して)変換?:
できるため、式はあいまいになります。規格によるとint
Foo
Foo
int
このプロセスを使用して、第2オペランドを第3オペランドに一致するように変換できるかどうか、および第3オペランドを第2オペランドに一致するように変換できるかどうかを判別します。両方を変換できる場合、または一方を変換できるが変換があいまいな場合、プログラムの形式が正しくありません。
Foo
あなたがどのように変換されるかを説明する段落int
:
5.16/3
についてcondition ? E1 : E2
:
それ以外の場合、2番目と3番目のオペランドの型が異なり、どちらかが(おそらくcv修飾された)クラス型である場合、これらのオペランドのそれぞれを他の型に変換しようとします。[...] E2が右辺値に変換された場合に式E2が持つタイプ(またはE2が右辺値の場合はそのタイプ)にE1を暗黙的に変換できる場合、E1はE2と一致するように変換できます。
4.3
「暗黙的に変換された」について:
T t = e;
いくつかの発明された一時変数tについて、宣言が整形式である場合に限り、式eを暗黙的に型Tに変換できます。
8.5/14
コピーの初期化について(T t = e;
)
ソースタイプが(おそらくcv修飾された)クラスタイプである場合、変換関数が考慮されます。該当する変換関数が列挙され(13.3.1.5)、過負荷解決(13.3)によって最適なものが選択されます。そのように選択されたユーザー定義の変換は、初期化式を初期化されるオブジェクトに変換するために呼び出されます。変換を実行できないか、あいまいな場合、初期化の形式が正しくありません。
13.3.1.5
変換関数の候補について
Sとその基本クラスの変換関数が考慮されます。S内に隠されておらず、タイプTまたは標準の変換シーケンス(13.3.3.1.1)を介してタイプTに変換できるタイプを生成するものが候補関数です。