2013-01-16 11 views
13

あいまいさのために複数のキャスト演算子が定義されていると、以下のコードでコンパイラエラーが発生することが予想されます。オーバーロードされたキャスト演算子の優先順位

#include <iostream> 
#include <sstream> 

struct A 
{ 
    operator const char*() { return "hello world\n"; } 
    operator float()  { return 123.0F; } 
    //operator int()   { return 49; } 
}; 

int main() 
{ 
    A a; 
    std::stringstream ss; 
    ss << a; 
    std::cout << ss.str(); 
    return 0; 
} 

つのみ数値キャスト演算子が定義されているようにする代わりに、限り、それはエラーなし、警告なしでコンパイル、および数値キャストがoperator const char *()に優先して使用されます。宣言された演算子の順序は違いはありません。

'operator <<' is ambiguous

は、キャストのための優先順位のルールがある、またはなぜコンパイラはデフォルトで、数値のキャストを選ぶん:私は、私は最初から期待されるものを手に入れる

しかしoperator int()operator float()場合の両方が、定義されていますか?私は明示的にキャストを意味する必要があることを理解していますが、私の質問はコンパイラが行うデフォルトの選択です。


編集:コンパイラMSVC 2010を使用

+0

私はそこに優先順位があることには依存しません。あなたが意味するものを入力してください。単に明示的なキャストを使用します。 'ss << static_cast (a);' – andre

+0

私はあなたの例をコンパイルして、g ++は "ss << a '"の演算子<<'のために "error:ambiguous overload"を返します。したがって、少なくともg ++は期待どおりに動作しています。 –

+1

これはコンパイラに依存するようです。どのコンパイラを使用していますか? – SztupY

答えて

4

変換はC++標準の13.3.3.1に従ってランク付けされます。特に、あなたの例に関連するユーザ定義の変換シーケンスは、13.3.3.1.2/1によって規定されています。

"ユーザ定義の変換シーケンスは、ユーザ定義の変換(12.3.2)で指定されている場合、最初の標準変換シーケンスは、ソースタイプをオブジェクトの暗黙オブジェクトパラメータに変換します。変換機能 "

ここですべての変換シーケンスが含む:

  1. 変換関数の暗黙のオブジェクトパラメータのソース・タイプの架空の変換;
  2. ユーザ定義の変換。
  3. 入力タイプoperator <<への恒等変換。

これらの変換シーケンスはすべて同じランクを持ちます。したがって、コールはあいまいである必要があります。そうでなければ、コンパイラのバグです。

+1

あなたの答えは誤解を招きます。なぜなら、ユーザー定義の変換が必要な型に直接変換するため、*ここには「第2の標準変換」*が含まれてはならないからです。だから、呼び出しはあいまいであるべきですが、あなたが3番目の段落に与える理由ではありません。 –

+0

@ChristianRau:13.3.3.1.2/1が言っていることを正しく理解している場合、ユーザー定義の変換は常に* 3段階の変換です。最初の手順は架空のものです。 "最初の標準変換シーケンスでは、変換関数の暗黙のオブジェクトパラメータにタイプしてください。 –

+1

はい、最初と2番目の標準コンバージョンはno-opsです。この場合、ターゲットタイプはすでに(中間の)ユーザー定義の変換によって到達されています。だから、整数型の浮動小数点変換やポインタ変換のランクが同じではない(これは重要ではない)が、すべて同じ初期初期化変換とそれに続くユーザ定義の**、その後に同じ(ノーオペレーション)の第2標準変換**が続きます。 –

関連する問題