10

参照への変換演算子がある場合、この演算子は への変換よりも優先されるようboolです。なぜこれが起こるのですか? どうすれば修正できますか?

(問題があれば、GCC 4.5 を使用しています。GCC-4.7.2 でも同じ動作が見られることを ideone で確認しました。)

次のことを前提とします。

class B {
protected:
    const int a_;
    int b_;
    B (int b, int a) : a_(a), b_(b) {}
public:
    operator bool () const { return b_ == a_; }
};

class D1 : public B {
public:
    D1 (int b = 0, int a = 0) : B(b, a) {}
    operator int () const { return b_; }
};

class D2 : public B {
public:
    D2 (int b = 0, int a = 0) : B(b, a) {}
    operator int & () { return b_; }
};

次に、これらが次のような単純なプログラムで使用されているとします。

int main () {
    if (D1 d1a = D1('a', 'a')) std::cout << "d1a\n";
    if (D1 d1b = D1('b', 'a')) std::cout << "d1b\n";
    if (D2 d2a = D2('a', 'a')) std::cout << "d2a\n";
    if (D2 d2b = D2('b', 'a')) std::cout << "d2b\n";
    return 0;
}

このプログラムの出力は次のとおりです。

d1a
d2a
d2b

が出力に含まれていないことに注意してくださいd1b。これは、 への変換がbool期待どおりに機能したことを意味しD1ます。しかし、 についてD2は、参照型への変換が変換よりも優先されたようboolです。なぜこれが起こったのですか?チェックで変換を優先D2できるようにする簡単な変更はありますか?boolif

現在、D1代入演算子を使用して追加し、参照の動作を実現しています。

4

2 に答える 2

9

実際、それは とは何の関係もありません。それは-nessint&の問題です:const

operator bool () const { return b_ == a_; }
              /* ^^^^^ */
              /* vvvvv */
operator int & () { return b_; }

d2aD2ではなく であるconst D2ため、非 const 変換演算子の方が適しています。のように書くと

operator const int & () const { return b_; }

期待どおりの動作が得られます。 http://ideone.com/vPPPYVを参照してください。

オブジェクトのバージョンoperator const int&を使用しても干渉しないことに注意してくださいconst

if (const D1 d1a = D1('a', 'a')) std::cout << "d1a\n";
if (const D1 d1b = D1('b', 'a')) std::cout << "d1b\n";
if (const D2 d2a = D2('a', 'a')) std::cout << "d2a\n";
if (const D2 d2b = D2('b', 'a')) std::cout << "d2b\n";
于 2013-07-11T21:56:22.540 に答える