According to the wikipedia page for Parametric Polymorphism:
Some implementations of type polymorphism are superficially similar to parametric polymorphis
The article you linked to explains that. The very text you quoted actually gives one example of something that sets C++'s templates apart from pure parametric polymorphism: C++ template specialisation.
It continues on this theme:
Following Christopher Strachey,[2] parametric polymorphism may be contrasted with ad hoc polymorphism, in which a single polymorphic function can have a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied. Thus, ad hoc polymorphism can generally only support a limited number of such distinct types, since a separate implementation has to be provided for each type.
Thus, as described, C++ templates come close to — but are not exactly — parametric polymorphism.
Why is C++ said to only implement something superficially similar to parameterized polymorphism? In particular, aren't templates an example of full on parametric polymorphism?
Templated functions in C++ work on the basis of "substitution" of the parameter. Which essentially means that the compiler generates yet another version of the function where the template arguments are hardcoded into the function.
Suppose you have this in C++:
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
int i = add(2, 3);
double d = add(2.7, 3.8);
return i + (int)d;
}
During compilation, that will result in two functions: int add(int a, int b) { return a + b; }
and double add(double a, double b) { return a + b; }
One function will ONLY handle ints, and the other will ONLY handle doubles. No polymorphism.
So really, you end up with as many implementations as the number of argument variations.
"But why isn't this parametric polymorphism?" you might ask?
You need the full source code of the 'add' function, in order to call it with your own particular variation of something that overloads the binary '+' operator! - That's the detail that makes the difference.
If C++ had proper parametric polymorphism, like C# for instance, your final compiled implementation of 'add' would contain enough logic to determine at runtime what the '+' overload would be for any given parameter acceptable to 'add'. And you wouldn't need the source code for that function, to call it with new types you invented.
What does this mean in reality?
But don't understand this as if C++ is less powerful or C# being more powerful. It's simply one of many language feature details.
If you have the full source available for your templated functions, then C++'s semantics are far superior. If you only have a static or dynamic library at your disposal, then a parametric polymorphic implementation (e.g. C#) is superior.