2016-07-08 4 views
1

ハンドルの周囲にラッパーがあります(intと表示されます)。しかし、私はまた、if条件でこれを簡単にチェックしたいと思います。 -1 or <0は無効な値です。私のアイデア:私は簡単に機能intを取り、すべてのチェックが合格にFooを渡すことができユーザー定義のブール変換の優先順位

#include <cassert> 

struct Foo{ 
    int i; 
    Foo(int i): i(i){} 
    operator int() const { return i; } 
    operator bool() const { return i >= 0; } 
}; 

int main(){ 
    Foo a(0); 
    if(a) 
     ; 
    else 
     assert(false); 
    if(!a) 
     assert(false); 
    assert(!!a); 
    Foo b(1); 
    assert(!!b); 
    assert(b); 
    assert(a != b); 
    Foo c(-1); 
    Foo d(-1); 
    assert(!c); 
    assert(c==d); 
    Foo e(-2); 
    assert(c!=e); 
} 

この方法です。しかし、私はint変換のブール変換よりも優先順位が心配です。何かありますか? if(Foo(...))/if(!Foo(...))/if(!!Foo(...))は常にブール変換を行いますが、直接比較ではint変換が行われるので、Foo(1) != Foo(0)Foo(1) != Foo(2)は常に指定できますか?

標準(C++ 98)は、bool/intのユーザー定義の変換には順序を入れていないようです。

+1

C++ 98を使用する必要がありますか? C++ 11以降では、 '明示的な変換'演算子 'を提供しています。これは、' bool'への正しい変換が主な根拠の1つであったことを保証します。意思決定に使用すると非常に間違った結果を生む可能性があります。古いC++を使用する必要がある場合は、「安全なブール」イディオムを調べてください。 –

+0

はい、C++ 98を使用する必要があります。私は比較のために選ばれるかもしれないint-conversionをまだ持っているので、安全なブールのイディオムがここで助けてくれるとは思わない。 – Flamefire

答えて

2

(!!はFoo(...))は、常にブール変換

を取る場合、私は/(Fooの(...))の場合/(!はFoo(...))場合に、確認することができます

はい。 operator!とifステートメントの条件では、式をboolに変換する必要があります。 intを使用した変換では、ユーザー定義の変換をintにしてから、標準変換をboolにする必要があります。直接boolへの変換では、その1つのユーザー定義変換のみが必要です。 1つ(後者)の変換は2つ(前者)よりも優先されます。

一方、直接比較では、Foo(1)!= Foo(0)とFoo(1)!= Foo(2)は常に与えられます。

いいえ両方のコンバージョンは同じようにランク付けされており、意図しているのはあいまいです。あいまいな変換は、プログラムを不正な形にします。

解決策:operator==(const Foo&, const Foo&)operator!=(const Foo&, const Foo&)を定義するか、比較の前に明示的にキャストしてください。

+0

申し訳ありませんが、これは動作します。 g ++はあいまいさには言及しませんが、clang(3.8)は – Flamefire

+0

@Flamefire興味深いことに注意してください。私は、この場合に警告を表示しないことは、規格に準拠していないと考えています。 – user2079303

+0

g ++ 4.8.5を使用しています。はい、私はそう思っていたでしょう。 '-Wall -Wextra'は何も表示しません – Flamefire

関連する問題