Are there situations when self-assignment is useful?
Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself. Consider the case where you have a user-provided assignment operator because each individual object has some kind of identifier, which you don't want to copy. Well, you can "copy" the other values just fine in self-assignment cases. So inserting an invisible self-assignment test is just adding a pointless and potentially costly conditional branch.
So it's not about self-assignment being useful; it's about self-assignment not always needing protection.
Furthermore, C++ generally doesn't like adding code like that to your code without you explicitly asking for it. It's typically done in terms of whole functions, not part of functions. Even destructor calls at the end of blocks are something you asked for when you put the object to be destroyed on the stack.
There are algorithms where it can happen.
You know the lhs and rhs might be the same but it is just simpler to do the assignment than check. E.g., consider
a = std::min(a,b);
- simpler and perhaps easier to understand thanif (a > b) a = b;
- now consider more complicated examples of similar things.You don't know whether lhs and rhs might be the same, because they may have been passed in from somewhere else.
These algorithms where it can happen are not uncommon.