在运算符查找中,成员不优先于非成员
In operator lookup no preference is given to members over nonmembers
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
中的a
和b
未声明为const
,因此对于成员运算符,左侧操作数的隐式转换序列更短(更好)。它不需要a
从A
到const A
的资格转换。这就是它成为更好候选人的原因。这就是选择您的会员功能版本的原因。
为了使两个版本等效,您必须将const
添加到您的成员运营商声明中
class A
{
public:
bool operator==(const A&) const
{
return true;
}
};
这将立即使您的CCD_ 10比较不明确。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 在C++中重载运算符时,为什么T*优先于bool
- 为什么 ADL 优先于'std namespace'中的函数,但等于用户定义命名空间中的函数?
- 为什么重载优先于ADL中的显式专用化
- 成员声明顺序在类中如果彼此依赖,则为最优解