为什么转换为引用会干扰转换为bool?

jxh*_*jxh 10 c++

似乎如果我有一个转换运算符到一个引用,这个运算符将优先于转换为a bool.为什么会发生这种情况,我该如何解决?

(如果重要的话,我正在使用GCC 4.5.我在ideone上验证了GCC-4.7.2发现了相同的行为.)

假设如下:

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_; }
};
Run Code Online (Sandbox Code Playgroud)

然后,假设它们在如下的简单程序中使用:

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;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是:

d1a
d2a
d2b
Run Code Online (Sandbox Code Playgroud)

请注意,d1b它不在输出中,这意味着转换bool按照我预期的方式工作D1.但是,因为D2转换到引用类型似乎优先于bool转换.为什么会这样?我可以做一个简单的更改,D2以允许bool转换优先于if支票吗?

目前,我正在使用D1并向其添加赋值运算符以实现引用的行为.

Zet*_*eta 9

实际上,它与之无关int&,这是一个问题const:

operator bool () const { return b_ == a_; }
              /* ^^^^^ */
              /* vvvvv */
operator int & () { return b_; }
Run Code Online (Sandbox Code Playgroud)

d2a是a D2,而不是a const D2,因此非const转换运算符更适合.如果你把它写成

operator const int & () const { return b_; }
Run Code Online (Sandbox Code Playgroud)

您将获得预期的行为,请访问http://ideone.com/vPPPYV.

请注意,operator const int&即使您使用const对象的版本也不会产生干扰,以下行仍会导致您的预期行为(请参阅http://ideone.com/DTE0xH):

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";
Run Code Online (Sandbox Code Playgroud)