I chose to provide ordinary overloading and multi-type type-classes in my language Felix.
I consider (open) overloading essential, especially in a language which as a lot of numeric types (Felix has all C's numeric types). However unlike C++ which abuses overloading by making templates depend on it, Felix polymorphism is parametric: you need overloading for templates in C++ because templates in C++ are badly designed.
Type classes are provided in Felix as well. For those that know C++ but don't grok Haskell, ignore those who describe it as overloading. It isn't remotely like overloading, rather, it is like template specialisation: you declare a template which you don't implement, then provide implementations for particular cases as you need them. The typing is parametrically polymorphic, the implementation is by ad hoc instantiation but it is not intended to be unconstrained: it has to implement the intended semantics.
In Haskell (and C++) you cannot state the semantics. In C++ the "Concepts" idea is roughly an attempt to approximate the semantics. In Felix, you can approximate the intention with axioms, reductions, lemmas and theorems.
The main, and only advantage of (open) overloading in a well principled language like Felix is that it makes it easier to remember library function names, both for the program writer and for the code reviewer.
The primary disadvantage of overloading is the complex algorithm required to implement it. It also doesn't sit very well with type inference: although the two are not entirely exclusive, the algorithm to do both is complex enough the programmer probably wouldn't be able to predict the results.
In C++ this is also a problem because it has a sloppy matching algorithm and also supports automatic type conversions: in Felix I "fixed" this problem by requiring an exact match and no automatic type conversions.
So you have a choice I think: overloading or type inference. Inference is cute, but it is also very hard to implement in a way that properly diagnoses conflicts. Ocaml, for example, tells you where it detects a conflict, but not where it inferred the expected type from.
Overloading is not much better, even if you have a quality compiler that tries to tell you all the candidates, it can be hard to read if the candidates are polymorphic, and even worse if it's C++ template hackery.