看来,如果我有引用的转换运算符,则该运算符将优先于到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_; }
};

然后,假设它们在像这样的简单程序中使用:
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进行简单的更改,以使bool转换在if检查中优先吗?

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

最佳答案

实际上,它与int&无关,这是const -ness的问题:

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也不会干扰,以下几行仍会导致您预期的行为(请参阅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";

关于c++ - 为什么转换为引用会干扰转换为bool?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17604002/

10-11 22:07
查看更多