0

クラス宣言内でオーバーロードされた演算子:

class Asdf{

    operator float() const;                 
    Asdf operator+(const Asdf&) const;
    Asdf operator+(float);

}

int main()

{
    Asdf object1, object2, object3;

    //Receiving error: "more than one operator '+' matches these operands"
    object1= object2 + object3;

    _getch();
    return 0;
}

エラー:

   :error C2666: 'Asdf::operator +': 3 つのオーバーロードの変換が似ています

   :「Asdf Asdf::operator +(float)」の可能性あり

   :'Asdf Asdf::operator +(const Asdf &) const'

オーバーロードされた変換演算子で使用されるすべての変換を削除するとfloat、コードは正しくコンパイルされます。

4

2 に答える 2

3

これは、変換演算子がクラスから float への暗黙的な手段を提供するために発生しています。したがって、フロートを含む他の加算演算子が邪魔になります。

これを改善するために、本当にその変換を可能にしたい場合の最善の解決策は、それを明示的にマークすることです:

explicit operator float() const;

Asdf a;
float f = static_cast<float>(a);

ただし、これは C++11 でのみ機能します。C++03 では、代わりに関数を使用することをお勧めします。

float toFloat() const;

Asdf a;
float f = a.toFloat();
于 2012-09-30T22:05:32.713 に答える
3

暗黙の変換演算子は、特に暗黙のコンストラクターと組み合わせた場合に、この種のあいまいさを招く傾向があります。

C++コーディング標準から:

  1. 暗黙的な型変換を避けるために、オーバーロードを検討してください。

必要以上にオブジェクトを乗算しない (Occam's Razor): 暗黙的な型変換は構文上の利便性を提供します (ただし、項目 40 を参照してください)。しかし、一時オブジェクトを作成する作業が不要で、最適化が適切な場合 (項目 8 を参照)、オーバーロードされた関数に、共通の引数の型と正確に一致し、変換を引き起こさないシグネチャを提供できます。

すべての変化が進歩であるとは限りません。暗黙の変換は、多くの場合、利益よりも害を及ぼす可能性があります。定義した型との間の暗黙的な変換を提供する前によく考え、明示的な変換 (明示的なコンストラクターと名前付き変換関数) に依存することを好みます。

これの多くは、暗黙的な変換を提供することから生じる可能性のある効率性と予期しない動作に関係しますが、暗黙的な変換演算子やコンストラクターを提供するときに簡単に遭遇する可能性のある種類の副作用には、関数のオーバーロードによるあいまいなエラーが含まれます。

解決策: オペレーターを明示的にするか、それを提供しないようにしてください。便利かもしれませんが、このような厄介な驚きを招く可能性があります (コンパイラ エラーは実際には最も厄介なものではありません)。

于 2012-09-30T22:09:08.017 に答える