1

Stroustrup写道:在运算符查找中,没有优先给非会员的成员

考虑一个二元运算符@。如果x的类型为X,y的类型为y,则x @ y如下解析:

•如果X是一个类,请将operator @作为X的成员或作为X的基的成员;和

•在围绕x @ y的上下文中查找operator @的声明;和

•如果X在名称空间N中定义,请在N中查找operator @的声明;和

•如果Y在命名空间M规定,找运营商@的声明中M.

声明几个运营商@ S可以被发现和重载决策规则(§12.3)来找到最好的匹配,如果有的话。只有在运算符至少有一个用户定义类型的操作数时才应用此查找机制。因此,将考虑用户定义的转换(第18.3.2节,第18.4节)。 请注意,类型别名仅是同义词,而不是单独的用户定义类型(第6.5节)。 一元运算符类似地解析。

请注意,在运算符查找中,不会优先给非成员上的成员。这与查询命名函数不同

那么什么是大胆的表达。如果类有成员,并且同时有非成员函数可以在上下文中使用,那么对成员没有优先权?例如

class A 
{ 
public: 
    bool operator==(const A&) 
    { 
     return true; 
    } 
}; 

bool operator==(const A&, const A&) 
{ 
    return true; 
} 

int main() 
{ 
    A a, b; 
    a == b; 
} 

我认为(和编译器同意我:)),其成员函数应该叫,但上面没有偏好书面应给予成员运算符。那么Stroustrup究竟意味着什么?

回答

2

您的代码只能编译,因为您的操作符在此上下文中不相同。根据隐式转换序列排序的规则,一个比另一个好。

请注意,您的成员操作符缺少第一个(左)参数的const限定。它实际上代表bool operator==(A&, const A&)

由于您在mainab不声明为const,对于左侧操作数的隐式转换序列为(越好)成员运营商。它不要求aAconst A的资格转换。这是什么使它成为一个更好的候选人。这就是您选择成员功能版本的原因。

为了让相当于两个版本必须添加const到您的会员运算符声明

class A 
{ 
public: 
    bool operator==(const A&) const 
    { 
     return true; 
    } 
}; 

,这将立即使你的a == b比较暧昧。