2017-02-10 6 views
2

ABの2つのクラスがあり、それぞれがoperator bool()を定義しています。if(a!= b)

私は最近によって引き起こされたバグに出くわした:GCC 4.9.1の下で罰金コンパイル

A a; 
B b; 
if(a!=b) 
{ 
    //... 
} 

コードと暗黙的に比較の前にBOOLするaとbを変換します。

これを防止し、コンパイルエラーを引き起こし、プログラマがAとBによって提供される明示的な変換関数を使用するようにすることは可能ですか? AとBの宣言は無関係でなければなりません。異なるヘッダーにあります。

+1

あなたは '演算子をオーバーロードすることができれば何が起こるか見ることができます例です。

別のオプションは、暗黙のint型の変換を削除することです!=(A、B) '、またはあなたのブール変換を'明示的に 'にする。 –

+3

' bool' 'explicit'への変換を行いますか?これは通常適切なことであり、 'if(a)'は文脈上 'bool' *に変換される*と考えられます。 – BoBTFish

+0

あなたが「変換」と言うとき、あなたは「比較」を意味しますか? –

答えて

2

明白な方法はAまたはB(またはその両方)に明示的にoperator bool()とマークすることです。コンパイラエラーが発生します。 AまたはB - そのような暗黙的な変換が意図したとおりに機能する他の用途がコンパイルされないことがあることに注意してください。無料のランチはありません。

コードの目的は、おそらくオブジェクト(または何らかの方法でデータメンバー)を比較することです。それがそうであるならば、それはまた、適切な場合があり値によって一つ以上を渡し、種類によって

bool operator!=(const A&, const B&);  // usage a != b 
    bool operator!=(const B&, const A&); // usage b != a 

を供給価値があるだろう[あなたはそれは設計上の選択です]。代わりに(例えば、両方のタイプがstruct/classタイプの場合)Aのメンバーとしてbool operator!=(const B &) const、およびBのメンバーとしてbool operator!=(const A &) constを実装することができます。

operator!=()に2種類のタイプが指定されている場合は、他の比較演算子(==など)を指定することも適切な場合があります。しかしそれは設計の決定です。

+0

演算子について説明できますか?私はこのオペレータがここに関わっていることを知らなかったのですが、これはエラーですか? – galinette

+0

比較演算子のデータメンバをクラスのメンバーにするのは良い考えです。通常、プライベートメンバにアクセスする必要はないからです。 – SebNag

+0

申し訳ありません - 書き込みが速すぎます。 '演算子bool'。私は訂正します。 – Peter

1

もう1つの「ハック」は、すでに言及したM.Mと同じようにブール変換を明示的にすることですが、これによっていくつかの問題が発生します。

class A { // same for class B 
public: 
    explicit operator bool() { 
     // some code 
     return (true || false) && !(false && true); 
    } 
}; 

今すぐ if(a==b)はもうコンパイルされませんが、 if(a)if(b)意志:

このような何か。 これはですが、aは整数にキャストされているため、if(a==true)などの予期しない動作ももうコンパイルされません。最初はif(a==b)がコンパイルされていた理由もあります。 operator int() = delete;

Hereあなたはarroundのプレーと変換演算子を持つあなたの混乱...

関連する問題