I don't think this is fair. Any approach to parametric types has to make some very hard trade-offs. C++ sacrificed:
* Fast, modular compilation
* Straightforward error messages
* Low cognitive overhead
In return:
* Templates perform as fast as hand-instantiated types. This is something some other languages like Java definitely cannot claim and is a key requirement for C++.
* Template functions can have complex constraints on their template parameters. Deferring type checking until after instantiation means you can do all sorts of interesting things with the template parameter and as long as all of those operations happen to work with the instantiated type, it's allowed. Most other languages place much more stringent restrictions on the expressiveness of generics. For example, in Java, you can't do "new T()". In C#, you can, but you can't do "new T(...)" with any kind of argument list.
Those are both really valuable features, especially in a language where performance is so critical.