> множественное наследование сложно использовать
Простой пhимер: А имеет два подкласса: B и C, от них происходит D.
Если родительские классы имеют общего предка (A), то в потомке (D) будет несколько экземпляров этого предка. С каким будут работать унаследованные методы в общем случае неизвестно. При приведении указателя D* к A* также непонятно, на что он будет указывать.
Это можно исправить, объявив наследование от A, как virtual в B и C, но работать это будет значительно медленнее и инициализацию такого предка придётся делать в каждом потомке (B, C, D и далее по иерархии), а не только в непосредственных B и C. Это не только неудобно, но и не вписывается в ООП. Кроме того, если A,B и C объявлены в сторонней библиотеке, такая операция вообще невозможна.
> перегрузка через virtual неудобна
Не могу обосновать. Я не считаю её неудобной. Мне всегда нравилось.
> исключения трудно реализовать в компиляторе, поэтому если и речь идет о многоплатформенности, то лучше о них забыть
Забыть о них не получится, т.к. они используются в языке (оператор new, например, их использует). Другое дело, что мне, например, они неудобны, но я вообще склонен избегать выходов управления и середины функции, как, извините за грубость, оператора goto. В ряде случаев, впрочем, использую.
> шаблоны — не самый простой способ генеративного программирования
По моему, он достаточно прост. Может быть, даже слишком: с помощью шаблонов очень легко раздуть программу массой однотипного кода.