仅与类的其他对象进行比较时,是否有任何理由不重载operator ==作为成员? [英] Is there any reason to not overload operator== as member, when only comparing to other object of the class?
问题描述
我一直在互联网上寻找答案,但找不到任何答案.给出的唯一原因似乎与与不同类型的对象(例如MyClass == int
)进行比较有关.但是最常见的用例是将一个类实例与同一类的另一个实例进行比较,而不是与任何不相关的类型进行比较.
换句话说,我确实了解以下问题:
struct A {
bool operator==(int b);
};
但是我找不到最明显的用例不使用成员函数的充分理由:
struct A {
bool operator==(const A&);
};
- 最典型的重复什么运算符重载的基本规则和习惯用法是什么?凭经验说将非二进制运算符重载为非成员".
- 运算符重载:成员函数与非成员函数?给出了上面提到的示例-如果您要将此运算符与另一个类/原始类型的实例一起使用 ...
- CppCoreGuidelines 含糊不清,"如果您使用成员函数,您需要两个,我认为这适用于与不同类型的对象进行比较.
- 为什么operator<是非成员函数吗?提到"非成员函数在隐式转换中发挥更好的作用",但似乎左手操作数又不是该类的实例.
另一方面,成员超载似乎有几个积极方面:
- 不需要成为函数的朋友或为成员提供吸气剂
- 它始终可供班级用户使用(尽管这也可能是不利的一面)
- 查找没有问题(由于某种原因,这在我们的GoogleTests中似乎很常见)
是否将重载operator==
作为非成员函数仅仅是为了使其与其他类中可能的重载保持一致?还是有其他原因使其成为非会员?
好吧,在您的问题中,您确实忘记了const
限定成员函数的功能,并且偶然地编写bool operator==(A&, const A&);
会更困难.>
如果您有隐式构造函数,具有隐式转换为A
的类或具有优先级更高的operator==
的基类,则成员函数在左侧时将不起作用,而在左侧在右边.尽管大多数时候隐式转换不是一个好主意,但是继承可能会导致问题.
struct A {
A(int); // Implicit constructor
A();
bool operator==(const A&) const;
};
struct B : A {
bool operator==(const B&) const;
};
void test() {
A a;
B b;
// 1 == a; // Doesn't work
a == 1;
// b == a; // Doesn't work; Picks `B::operator==(const B&) const;`
a == b; // Picks `A::operator==(const A&) const`, converting `b` to an `A&`.
// Equality is no longer symmetric as expected
}
将来,使用C ++ 20 operator<=>
,您很可能总是将其实现为成员函数(即What are the basic rules and idioms for operator overloading? says "overload binary operators as non-member" as rule of a thumb.
On the other hand, member overload seems to have a couple positive sides:
- No need to befriend the function or to provide getters for members
- It is always available to class users (although this might be the downside also)
- No problems with lookup (which seems to be common in our GoogleTests for some reason)
Is overloading operator==
as non-member function just a convention to keep it the same with possible overloads in other classes? Or are there any other reasons to make it non-member?
Well, in your question, you did forget to const
qualify the member function, and it would be harder to write bool operator==(A&, const A&);
by accident.
If you had an implicit constructor, a class with implicit conversion to A
or base class with an operator==
with higher priority, the member function wouldn't work if it was on the left, but would if it was on the right. Although most of the time implicit conversions are a bad idea, inheritance could reasonably lead to a problem.
struct A {
A(int); // Implicit constructor
A();
bool operator==(const A&) const;
};
struct B : A {
bool operator==(const B&) const;
};
void test() {
A a;
B b;
// 1 == a; // Doesn't work
a == 1;
// b == a; // Doesn't work; Picks `B::operator==(const B&) const;`
a == b; // Picks `A::operator==(const A&) const`, converting `b` to an `A&`.
// Equality is no longer symmetric as expected
}
In the future, with the C++20 operator<=>
, you will most likely always implement this as a member function (namely as auto operator<=>(const T&) const = default;
), so we know that this guideline may change.
这篇关于仅与类的其他对象进行比较时,是否有任何理由不重载operator ==作为成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!