在运算符查找中,成员不优先于非成员

In operator lookup no preference is given to members over nonmembers

本文关键字:成员 优先于 运算符 查找      更新时间:2023-10-16

Stroustrup写道:

考虑一个二进制运算符@。如果x是x类型,y是y类型,那么x@y的解析如下:

•如果X是一个类,则将运算符@作为X的成员或X的基的成员;和

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

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

•如果Y是在命名空间M中定义的,请在M中查找运算符@的声明。

几项声明operator@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;
}

我认为(编译器也同意我的观点:)应该调用成员函数,但如上所述,不应该优先考虑成员运算符。那么这句话到底是什么意思呢?

您的代码之所以编译,是因为您的运算符在此上下文中不等价。一个比另一个好,根据隐式转换序列的排序规则。

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

由于main中的ab未声明为const,因此对于成员运算符,左侧操作数的隐式转换序列更短(更好)。它不需要aAconst A的资格转换。这就是它成为更好候选人的原因。这就是选择您的会员功能版本的原因。

为了使两个版本等效,您必须将const添加到您的成员运营商声明中

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

这将立即使您的CCD_ 10比较不明确。