Do not overload operators except in rare, special circumstances. Do not create user-defined literals.
A class can define that operators such as + and / operate on the class as if it were a built-in type. An overload of operator"" allows the built-in literal syntax to be used to create objects of class types.
Operator overloading can make code appear more intuitive because a class will behave in the same way as built-in types (such as int). Overloaded operators are more playful names for functions that are less-colorfully named, such as Equals() or Add().
For some template functions to work correctly, you may need to define operators.
User-defined literals are a very concise notation for creating objects of user-defined types.
While operator overloading can make code more intuitive, it has several drawbacks:
- It can fool our intuition into thinking that expensive operations are cheap, built-in operations.
- It is much harder to find the call sites for overloaded operators. Searching for Equals() is much easier than searching for relevant invocations of ==.
- Some operators work on pointers too, making it easy to introduce bugs. Foo + 4 may do one thing, while &Foo + 4 does something totally different. The compiler does not complain for either of these, making this very hard to debug.
- User-defined literals allow creating new syntactic forms that are unfamiliar even to experienced C++ programmers.
Overloading also has surprising ramifications. For instance, if a class overloads unary operator&, it cannot safely be forward-declared.
In general, do not overload operators. You can define ordinary functions like Equals() if you need them. Likewise, avoid the dangerous unary operator& at all costs, if there's any possibility the class might be forward-declared.
Do not overload operator"", i.e. do not introduce user-defined literals.
However, there may be rare cases where you need to overload an operator to interoperate with templates or "standard" C++ classes (such as operator<<(ostream&, const T&) for logging). These are acceptable if fully justified, but you should try to avoid these whenever possible. In particular, do not overload operator== or operator< just so that your class can be used as a key in an STL container; instead, you should create equality and comparison functor types when declaring the container.
Some of the STL algorithms do require you to overload operator==, and you may do so in these cases, provided you document why.
See also Copyable and Movable Types and Function Overloading.