Strictement, jamais. On peut toujours simuler à partir de l'héritage simple -- et d'un travail plus ou moins
important. Après la question est peut-être: quand est-ce qu'il devient préférable d'utiliser une solution à
base d'héritage multiple à une solution à base d'héritage simple?
Les réponses vont varier en fonction des goûts et de l'expérience passée des gens. La position de Joël
est assez commune: l'héritage multiple quand toutes les bases sauf une n'ont pas de membres donnée
passe généralement assez bien. Quand au moins deux bases ont des membres donnée, il y a souvent
une impression qu'il doit y avoir mieux, même si je ne connais personne qui préfère bâtir des constructions
complexes à base d'héritage simple quand ils ont besoin de surcharger dans une même classe des membres
virtuels de deux hiérarchies différentes. C'est le besoin même qui donne l'impression que la conception est
mal faite ou est trop contrainte -- par exemple parce que les deux hiérarchies proviennent de fournisseurs
différents. Il faut dire que les cas classiques qui ont besoin de données dans deux classes de bases ont
tendance à être des mixins qui sont mieux exprimés en C++ avec le CRTP ou d'autres techniques à base
de templates.
J'aimerais bien une fois pouvoir prendre des hiérarchies comme celles citées dans A Monotonic Superclass
Linearization for Dylan, qui a comparé des algorithmes de résolution d'ambiguité (en C++ on aurait une
erreur à la compilation dans ces cas, dans des langages comme Dylan et Common Lisp, non) sur un total
de 3296 classes et 701 cas d'héritage multiple, et voir quelle proportion serait naturellement traitée en
C++ par des techniques à base de template. À moins que quelqu'un connaisse une référence faisant une
telle analyse (c'est plus difficile à faire que dans le papier cité, qui comparait les résultats d'algorithmes
différents, sans examiner pourquoi on en était arrivé là).