Why don't C++ compilers define operator== and operator!=?
I am a big fan of letting the compiler do as much work for you as possible. When writing a simple class the compiler can give you the following for 'free':
operator=
) But it cannot seem to give you any comparison operators - such as operator==
or operator!=
. For example:
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
{ }
Is there a good reason for this? Why would performing a member-by-member comparison be a problem? Obviously if the class allocates memory then you'd want to be careful, but for a simple class surely the compiler could do this for you?
The compiler wouldn't know whether you wanted a pointer comparison or a deep (internal) comparison.
It's safer to just not implement it and let the programmer do that themselves. Then they can make all the assumptions they like.
The argument that if the compiler can provide a default copy constructor, it should be able to provide a similar default operator==()
makes a certain amount of sense. I think that the reason for the decision to not provide a compiler-generated default for this operator can be guessed by what Stroustrup said about the default copy constructor in "The Design and Evolution of C++" (Section 11.4.1 - Control of Copying):
I personally consider it unfortunate that copy operations are defined by default and I prohibit copying of objects of many of my classes. However, C++ inherited its default assignment and copy constructors from C, and they are frequently used.
So instead of "why doesn't C++ have a default operator==()
?", the question should have been "why does C++ have a default assignment and copy constructor?", with the answer being those items were in included reluctantly by Stroustrup for backwards compatibility with C (probably the cause of most of C++'s warts, but also probably the primary reason for C++'s popularity).
For my own purposes, in my IDE the snippet I use for new classes contains declarations for a private assignment operator and copy constructor so that when I gen up a new class I get no default assignment and copy operations - I have to explicitly remove the declaration of those operations from the private:
section if I want the compiler to be able to generate them for me.
UPDATE 2: Unfortunately this proposal didn't make it to C++17, so nothing is changing in the language with this regard for now.
UPDATE: The current version of the proposal which has very high chance to get voted into C++17 is here.
There is a recent proposal (N4126) on explicitly defaulted comparison operators, which has had very positive feedback from the standard committee, so hopefully we'll see it in some form in C++17.
In short, the proposed syntax is:
struct Thing
{
int a, b, c;
std::string d;
};
bool operator==(const Thing &, const Thing &)= default;
bool operator!=(const Thing &, const Thing &)= default;
Or in friend
form for classes with private fields:
class Thing
{
int a, b;
friend bool operator<(Thing, Thing) = default;
friend bool operator>(Thing, Thing) = default;
friend bool operator<=(Thing, Thing) = default;
friend bool operator>=(Thing, Thing) = default;
};
Or even in short form:
struct Thing
{
int a, b, c;
std::string d;
default: ==, !=, <, >, <=, >=; // defines the six non-member functions
};
Of course all this may change by the time this proposal is finally accepted.
链接地址: http://www.djcxy.com/p/2026.html