提问人:Alexey Starinsky 提问时间:2/9/2019 最后编辑:BarryAlexey Starinsky 更新时间:2/10/2019 访问量:165
没有运算符 ==() 的类的对象将转换为另一种类型
Objects of a class that does not have operator ==() are converted to another type
问:
为什么在以下代码中将类 A 的对象转换为 bool(或 int):
class A
{
public:
operator bool() const { return true; }
operator int() const { return 1; }
};
int main()
{
return A() == A();
}
目前尚不清楚它们被转换为什么?到 bool 还是到 int?
答:
我们需要找到如何处理.这将涉及寻找 的成员、非成员和内置候选人。在这种情况下,我们没有任何成员/非成员候选人,因此这部分很容易。==
==
内置的候选者来自 [over.built]/13(强调我的,并进行了删节):
对于每一对提升的算术类型 L 和 R,都存在以下形式的候选运算符函数
bool operator==(L, R);
提升的算术类型是提升后的整型和浮点型。任何小于 (including) 的整型都提升为 。( 提升为 ,但仍是“提升算术类型”)。对我们来说,这其中最重要的部分是“提升的算术类型”包括 ,但不包括 。因此,我们非常有效地内置了候选者,例如:int
bool
int
float
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
第二组由所有其他候选人组成。对于每个不是 的提升算术类型,我们有两个等效的转换序列:一个通过转换,一个通过转换。两者都不比另一个好。当我第一次写下这个答案时,我以为这意味着这些候选者会被拒绝——但令人惊讶的是,事实并非如此,正如 T.C. 指出的那样:模棱两可的转换序列与任何其他用户定义的转换序列相同。int
bool
int
因此,从第一组开始,我们有一个可行的候选者,它涉及用户定义的转换序列。从第二组开始,我们有很多转换序列模棱两可的候选者——重要的是,这些候选者被认为与第一组的候选者相当好。operator==(int, int)
因此,格式不正确。没有最可行的候选人。海湾合作委员会接受这一点是错误的。A() == A()
请注意,gcc 确实拒绝了同一想法的非常相似的其他表示:
void check(int, int);
void check(float, float);
check(A(), A()); // gcc and clang reject, msvc accepts
评论
cout
operator