From a 1995 interview with Alexander Stepanov in Dr Dobb's Journal: "I returned to generic library development in 1992 when Bill Worley, who was my lab director established an algorithms project with me being its manager. C++ had templates by then. I discovered that Bjarne had done a marvelous job at designing templates. I had participated in several discussions early on at Bell Labs about designing templates and argued rather violently with Bjarne that he should make C++ templates as close to Ada generics as possible. I think that I argued so violently that he decided against that. I realized the importance of having template functions in C++ and not just template classes, as some people believed. I thought, however, that template functions should work like Ada generics, that is, that they should be explicitly instantiated. Bjarne did not listen to me and he designed a template function mechanism where templates are instantiated implicitly using an overloading mechanism. This particular technique became crucial for my work because I discovered that it allowed me to do many things that were not possible in Ada. I view this particular design by Bjarne as a marvelous piece of work and I'm very happy that he didn't follow my advice."
In Ada, a generic must be instantiated, as for example:
package IntIo is new TextIo.IntegerIo(int);
package coerce is new UncheckedConversion(SomeTypeA, SomeTypeB);
In C++, Stroustrup set it up so you write something like:
ObjectOfTypeB := coerce<SomeTypeA,SomeTypeB>(ObjectOfTypeA);
Stroustrup had to use SOMETHING to indicate the generic and its specialization. He chose to overload angle brackets. This initially created problems. What if your template specialization required another template specialization, and you needed to close them both? The lexer sees two closing >, or >>, and recognizes that as a shift operation. A later language fix was required, to overload the shift operators << and >>.