10

似乎如果我有一个引用的转换运算符,这个运算符将优先于转换为 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_; }
};

然后,假设它们被用在一个像这样的简单程序中:

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并添加一个赋值运算符来实现引用的行为。

4

2 回答 2

9

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

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

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

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";
于 2013-07-11T21:56:22.540 回答
1

D1 d1a = D1('a', 'a');
D1 d1b = D1('b', 'a');
D2 d2a = D2('a', 'a');
D2 d2b = D2('b', 'a');
if (d1a) std::cout << "d1a\n";
if (d1b) std::cout << "d1b\n";
if (d2a) std::cout << "d2a\n";
if (d2b) std::cout << "d2b\n";

印刷

d1a
d2a

为了我。

你有

if (D2 d2a = D2('a', 'a')) std::cout << "d2a\n";
if (D2 d2a = D2('b', 'a')) std::cout << "d2b\n";

如果在这两种情况下不使用相同的名称会发生​​什么?如果我将第 4d1ad2a替换为

if (D2 d2b = D2('b', 'a')) std::cout << "d2b\n";
于 2013-07-11T21:47:33.313 回答