It is commonly known that when implementing an assignment operator one has to protect against self-assignment, at least when the class has non-POD members. Usually it is (or is equivalent to):
Foo& operator=(const Foo& other)
{
if (&other == this)
return *this;
... // Do copy
}
What were the reasons for not inserting the self-assignment protection automatically? Are there use cases when self-assignment does something non-trivial and practically useful?
Foo& operator=(const Foo& other)
{
if (&other == this)
{
// Do something non-trivial
}
else
{
// Do copy
}
return *this;
}
To summarize the answers and discussion by now
Looks like non-trivial self-assignment can never be really useful. The only option proposed was to put an assert
there in order to detect some logical errors. But there are quite legitimate self-assignment cases like a = std::min(a, b)
, so even this option is highly dubious.
But there are two possible implementations of a trivial self-assignment:
- Do nothing if
&other == this
. Always work, though may have negative performance impact due to an extra branching. But in a user-defined assignment operator the test must be almost always explicitly made. - Copy each member to itself. This is what is done by default. If the members use default assignment operators as well, it may be faster, because doesn't requre an extra branching.
I still don't see why the C++ standard could not guarantee that in a user-defined assignment operator &other != this
. If you want no branching, use the default operator. If you are redefining the operator, some test is needed anyway...
a < b
andb > a
return different results. – Rutter<<
and>>
with effectful operations. Maybe they figured someone might want to do similarly crazy things with=
. – Anh==
is not necessarily transitive. 😉 – Colwen