2015 更新:(double)obj
または、構文の代わりに構文を使用して変換機能を維持したい場合は、そのキーワードを前に付けてobj.to_double()
変換関数を作成します。explicit
変換をトリガーするには、明示的なキャストが必要です。個人的には、変換が toで.to_double
ない限り、構文が好きです.bool
if(obj)
explicit
if(obj.to_bool())
変換演算子をドロップします。どこまでもトラブルの元になります。のような機能を持っています
to_double()
または、double 値を返し、その関数を明示的に呼び出して double を取得する同様のもの。
当面の問題については、次の問題があります。
obj >= 10
その表現を考えてみましょう。組み込み演算子は、変換演算子 long double() を使用して、型のユーザー定義変換シーケンスによって最初の引数と一致します。ただし、関数は、int から long double への標準変換シーケンス (整数から浮動小数点への変換) によって 2 番目の引数と一致します。2 つの引数の変換がある場合は常にあいまいですが、少なくとも 1 つの引数がより適切に変換され、残りの引数が 1 回の呼び出しでより悪く変換されることはありません。あなたの場合、組み込みのものは2番目の引数によく一致しますが、最初の引数には一致しませんが、関数は最初の引数によく一致しますが、2番目の引数には一致しません。
紛らわしいので、いくつか例を示します (char から int への変換はプロモーションと呼ばれ、char から int 以外への変換 (変換と呼ばれます) よりも優れています)。
void f(int, int);
void f(long, long);
f('a', 'a');
最初のバージョンを呼び出します。最初のすべての引数をより適切に変換できるためです。同様に、次の場合でも最初の呼び出しが行われます。
void f(int, long);
void f(long, long);
f('a', 'a');
最初の変換はより良く、2 番目の変換はより悪い変換ではないためです。しかし、以下はあいまいです:
void f(char, long);
void f(int, char);
f('a', 'a'); // ambiguous
この場合はもっと興味深いです。最初のバージョンは、完全一致によって最初の引数を受け入れます。2 番目のバージョンは、完全一致で 2 番目の引数を受け入れます。しかし、どちらのバージョンも、他の主張を少なくとも同じようには受け入れていません。最初のバージョンでは 2 番目の引数の変換が必要ですが、2 番目のバージョンでは引数の昇格が必要です。したがって、プロモーションはコンバージョンよりも優れていますが、2 番目のバージョンの呼び出しは失敗します。
上記のケースと非常によく似ています。標準の変換シーケンス (int/float/double から long double への変換) は、ユーザー定義の変換シーケンス (MyClass から long double への変換) よりも優れていますが、オペレーターのバージョンは選択されません。 ) は、組み込み演算子がその引数に必要とするものよりも悪い引数からの変換を必要とします (完全一致)。
オーバーロードの解決は C++ では複雑な問題であるため、その微妙なルールをすべて思い出すことは不可能です。しかし、大まかな計画を立てることはかなり可能です。お役に立てば幸いです。