为什么在以下代码中将A类对象转换为bool(或int):
class A
{
public:
operator bool() const { return true; }
operator int() const { return 1; }
};
int main()
{
return A() == A();
}
尚不清楚它们将转换为什么?是布尔还是整数?
答案 0 :(得分:6)
我们需要找到处理==
的方法。这将涉及寻找==
的成员,非成员和内置候选人。在这种情况下,我们没有任何成员/非成员候选人,所以这部分很容易。
内置的候选词来自[over.built]/13(强调我的词并被删节):
对于每对推广的算术类型 L 和 R ,存在形式为
的候选算子函数
bool operator==(L, R);
promoted arithmetic types是升级后的整数类型和浮点类型。小于int
(包括bool
)promotes至int
的整数类型。 ({float
promotes到double
,但是float
仍然是“提升的算术类型”)。对于我们来说,这一点的重要部分实际上是“高级算术类型”包括int
,但不包括bool
。如此有效,我们内置了以下候选人:
bool operator==(int, int);
bool operator==(int, long);
bool operator==(long, int);
bool operator==(long, long);
bool operator==(int, float);
// etc.
此集中有很多个候选。但是我们基本上可以将它们分为两组。
第一组完全由以下组成:
bool operator==(int, int);
该候选人是可行的,我们拥有明确的最佳转换顺序,因为经历operator int() const
比经历operator bool() const
然后晋升要好。
第二组由其他所有候选人组成。对于不是int
的每个提升的算术类型,我们有两个等效的转换序列:一个通过bool
转换和一个通过int
转换。两者都不比另一个更好。当我第一次写这个答案时,我以为这意味着这些候选人将被拒绝-但令人惊讶的是,事实并非如此。指出:不明确的转换顺序是treated equivalently to任何其他用户定义的转换顺序。
因此,从第一组开始,我们有一个可行的候选方案,其中涉及用户定义的转换序列。在第二组中,我们有很多候选者的转换顺序不明确-重要的是,它们被认为等效于第一组中的operator==(int, int)
候选者。
结果是A() == A()
格式错误。没有最佳可行的候选人。 gcc接受这个错误。
请注意,gcc确实拒绝了与此想法非常相似的其他演示文稿:
void check(int, int);
void check(float, float);
check(A(), A()); // gcc and clang reject, msvc accepts