没有运算符 ==() 的类的对象将转换为另一种类型

Objects of a class that does not have operator ==() are converted to another type

提问人:Alexey Starinsky 提问时间:2/9/2019 最后编辑:BarryAlexey Starinsky 更新时间:2/10/2019 访问量:165

问:

为什么在以下代码中将类 A 的对象转换为 bool(或 int):

class A
{
public:

    operator bool() const { return true; }
    operator int() const { return 1; }
};

int main()
{
    return A() == A();
}

目前尚不清楚它们被转换为什么?到 bool 还是到 int?

++ 的 C++17

评论

2赞 Dustin Nieffenegger 2/9/2019
您可以随时添加一个语句来找出正在调用的语句。cout
0赞 Alexey Starinsky 2/9/2019
@GuillaumeRacicot在哪里添加“显式”?
0赞 Guillaume Racicot 2/9/2019
就在关键字之前operator
0赞 Alexey Starinsky 2/9/2019
你@GuillaumeRacicot试过这个?
0赞 Guillaume Racicot 2/9/2019
是的。现在它正确失败了。

答:

6赞 Barry 2/9/2019 #1

我们需要找到如何处理.这将涉及寻找 的成员、非成员和内置候选人。在这种情况下,我们没有任何成员/非成员候选人,因此这部分很容易。====

内置的候选者来自 [over.built]/13(强调我的,并进行了删节):

对于每一对提升的算术类型 LR,都存在以下形式的候选运算符函数

bool operator==(L, R);

提升的算术类型是提升后的整型和浮点型。任何小于 (including) 的整型都提升为 。( 提升为 ,但仍是“提升算术类型”)。对我们来说,这其中最重要的部分是“提升的算术类型”包括 ,但不包括 。因此,我们非常有效地内置了候选者,例如:intboolintfloatdoublefloatintbool

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() constoperator bool() const

第二组由所有其他候选人组成。对于每个不是 的提升算术类型,我们有两个等效的转换序列:一个通过转换,一个通过转换。两者都不比另一个好。当我第一次写下这个答案时,我以为这意味着这些候选者会被拒绝——但令人惊讶的是,事实并非如此,正如 T.C. 指出的那样:模棱两可的转换序列与任何其他用户定义的转换序列相同intboolint

因此,从第一组开始,我们有一个可行的候选者,它涉及用户定义的转换序列。从第二组开始,我们有很多转换序列模棱两可的候选者——重要的是,这些候选者被认为与第一组的候选者相当好。operator==(int, int)

因此,格式不正确。没有最可行的候选人。海湾合作委员会接受这一点是错误的。A() == A()


请注意,gcc 确实拒绝了同一想法的非常相似的其他表示:

void check(int, int);
void check(float, float);

check(A(), A()); // gcc and clang reject, msvc accepts

评论

1赞 T.C. 2/9/2019
具有模棱两可的转换序列不会使候选者不可行;如果候选人被选中,它只会使调用格式不正确。由于这样的序列被认为与其他所有用户定义的转换序列没有区别,因此根据标准,调用确实是模棱两可的。这里的问题是 [over.built] 的候选人名单太宽泛了。
0赞 T.C. 2/9/2019
是的,差不多。这可能是也可能不是预期的行为,但这是当前措辞所规定的。
0赞 Barry 2/10/2019
@T.C. 这似乎......错。但我不想用一根 5 英尺长的杆子碰到它。
0赞 Barry 2/10/2019
@T.C. SO 需要一个多作者的概念。