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

时间:2019-02-08 20:51:54

标签: c++ c++17

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

class A
{
public:

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

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

尚不清楚它们将转换为什么?是布尔还是整数?

1 个答案:

答案 0 :(得分:6)

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

内置的候选词来自[over.built]/13(强调我的词并被删节):

  

对于每对推广的算术类型 L R ,存在形式为

的候选算子函数      

bool operator==(L, R);

promoted arithmetic types是升级后的整数类型和浮点类型。小于int(包括boolpromotesint的整数类型。 ({float promotesdouble,但是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