似乎如果我有一个转化运算符到引用,此运算符将优先于转换为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
并为其添加赋值运算符以实现引用的行为。
答案 0 :(得分:9)
实际上,它与int&
无关,这是const
- ness:
operator bool () const { return b_ == a_; }
/* ^^^^^ */
/* vvvvv */
operator int & () { return b_; }
d2a
是D2
,而不是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";
答案 1 :(得分: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";
如果在这两种情况下不使用相同的名称,会发生什么? 如果我用
替换第4个,则输出中只有d1a
和d2a
if (D2 d2b = D2('b', 'a')) std::cout << "d2b\n";