我非常支持让编译器为你做尽可能多的工作。当编写一个简单的类时,编译器可以为你提供以下“免费”:
默认(空)构造函数
复制构造函数
一个析构函数
赋值运算符(operator=)
但是它似乎不能给你任何比较操作符——比如operator==或operator!=。例如:
class foo
{
public:
std::string str_;
int n_;
};
foo f1; // Works
foo f2(f1); // Works
foo f3;
f3 = f2; // Works
if (f3 == f2) // Fails
{ }
if (f3 != f2) // Fails
{ }
这有什么好的理由吗?为什么执行逐个成员的比较是一个问题?显然,如果类分配内存,那么你要小心,但对于一个简单的类,编译器肯定可以为你做这个?
定义default ==是不可能的,但是你可以定义default != via ==,你通常应该定义自己。
为此,你应该做以下事情:
#include <utility>
using namespace std::rel_ops;
...
class FooClass
{
public:
bool operator== (const FooClass& other) const {
// ...
}
};
详情请访问http://www.cplusplus.com/reference/std/utility/rel_ops/。
此外,如果您定义操作符<,则在使用std::rel_ops时,可以从它推导出<=、>、>=的操作符。
但是在使用std::rel_ops时应该小心,因为可以为您不期望的类型推导出比较运算符。
从基本操作符推断相关操作符的更可取的方法是使用boost::操作符。
boost中使用的方法更好,因为它为您只需要的类定义了operator的用法,而不是为作用域内的所有类定义了operator的用法。
您还可以从“+=”生成“+”,从“-=”生成“-”,等等…(见完整列表)
即使在c++ 20中,编译器仍然不会隐式地为你生成operator==
struct foo
{
std::string str;
int n;
};
assert(foo{"Anton", 1} == foo{"Anton", 1}); // ill-formed
但是自c++ 20以来,你将获得显式默认==的能力:
struct foo
{
std::string str;
int n;
// either member form
bool operator==(foo const&) const = default;
// ... or friend form
friend bool operator==(foo const&, foo const&) = default;
};
默认==执行成员式==(与默认复制构造函数执行成员式复制构造相同)。新规则还提供了==和!=之间的预期关系。例如,通过上面的声明,我可以写:
assert(foo{"Anton", 1} == foo{"Anton", 1}); // ok!
assert(foo{"Anton", 1} != foo{"Anton", 2}); // ok!
这个特定的特性(默认操作符==以及==和!=之间的对称)来自一个提议,该提议是更广泛的语言特性操作符<=>的一部分。
在这个视频中,STL的创造者Alex Stepanov在13:00左右回答了这个问题。总结一下,在见证了c++的发展之后,他认为:
It's unfortunate that == and != are not implicitly declared (and Bjarne agrees with him). A correct language should have those things ready for you (he goes further on to suggest you should not be able to define a != that breaks the semantics of ==)
The reason this is the case has its roots (as many of C++ problems) in C. There, the assignment operator is implicitly defined with bit by bit assignment but that wouldn't work for ==. A more detailed explanation can be found in this article from Bjarne Stroustrup.
In the follow up question Why then wasn't a member by member comparison used he says an amazing thing : C was kind of a homegrown language and the guy implementing these stuff for Ritchie told him he found this to be hard to implement!
然后他说,在(遥远的)未来,==和!=将隐式生成。