不过,我担心的是,为什么需要两个单独的定义?
您不必同时定义两者。
如果它们是互斥的,您仍然可以通过仅定义==
和<
旁边的std::rel_ops来简洁
形式 cppreference:
#include <iostream>
#include <utility>
struct Foo {
int n;
};
bool operator==(const Foo& lhs, const Foo& rhs)
{
return lhs.n == rhs.n;
}
bool operator<(const Foo& lhs, const Foo& rhs)
{
return lhs.n < rhs.n;
}
int main()
{
Foo f1 = {1};
Foo f2 = {2};
using namespace std::rel_ops;
//all work as you would expect
std::cout << "not equal: : " << (f1 != f2) << '\n';
std::cout << "greater: : " << (f1 > f2) << '\n';
std::cout << "less equal: : " << (f1 <= f2) << '\n';
std::cout << "greater equal: : " << (f1 >= f2) << '\n';
}
在任何情况下,询问两个对象是否相等确实有意义,但询问它们不相等是没有意义的?
我们经常将这些运算符与相等性联系起来。
尽管这是它们在基本类型上的行为方式,但没有义务将其作为自定义数据类型的行为方式。如果您不想返回布尔值,您甚至不必返回。
我见过人们以奇怪的方式重载运算符,却发现这对于他们的特定领域应用程序是有意义的。即使界面看起来显示它们是互斥的,作者也可能想要添加特定的内部逻辑。
(无论是从用户的角度,还是从实施者的角度)
我知道你想要一个具体的例子,
所以这里有一个我认为实用 的Catch 测试框架:
template<typename RhsT>
ResultBuilder& operator == ( RhsT const& rhs ) {
return captureExpression<Internal::IsEqualTo>( rhs );
}
template<typename RhsT>
ResultBuilder& operator != ( RhsT const& rhs ) {
return captureExpression<Internal::IsNotEqualTo>( rhs );
}
这些运算符在做不同的事情,将一种方法定义为另一种方法的 !(not) 是没有意义的。这样做的原因是框架可以打印出所做的比较。为此,它需要捕获所使用的重载运算符的上下文。