Hi all I have a doubt regarding templates and polymorphism. By definition polymorphism provides code reusability, and templates in some sense allows the user to use the same code by providing generic programming with different data types. So what is the benefit of using polymorphism over templates. It might be a silly questions but I am curious to know the exact difference.
-
1Templates provide static/compile time polymorphism. While *virtualism* provides dynamic polymorphism. – Alok Save May 11 '12 at 17:23
-
1What's different? Everything. Polymorphism is not even remotely about code reusability. Templates are. – Mooing Duck May 11 '12 at 17:23
-
2@MooingDuck: Polymorphism does allow code re-use. Old code (written against a polymorphic base class) using new code (written towards the same base class). – Nicol Bolas May 11 '12 at 17:30
-
1@Nicol : I think his point is that polymorphism _may_ allow code reuse, but that's not it's actual _purpose_. – ildjarn May 11 '12 at 17:38
-
Clearly, they are asking how best to solve a certain problem they're having. In that case, they didn't provide enough info about the problem. Some things are better solved using templates and others with polymorphism. – MathCrackExchange Aug 23 '22 at 00:37
2 Answers
You seem to misunderstand what polymorphism is.
Polymorphism, at its core, has nothing to do with derived classes. Polymorphism simply means the ability to use a type without knowing everything about it. Rather than using a concrete type, polymorphism relies on some form of prototype to define what types it takes. Any types that fit that prototype are accepted.
Runtime polymorphism, in C++, is provided by deriving classes from a base class that contains virtual functions. The base class and virtual functions form the polymorphic prototype. Code written to accept the base class that calls these virtual functions will accept any class instance derived from the base class.
Compile-time polymorphism is polymorphism that happens... at compile time ;) What this means is that the compiler must know what is going on. You may have written the C++ code against a polymorphic prototype, but the compiler doesn't care. You get specific concrete types post-compilation.
Compile-time polymorphism is provided by templates in C++. A template function or class can take any type which conforms to a prototype, usually called a "concept". Unlike base classes and virtual functions, the prototype is implicit: the prototype is defined only by how the type is used by the template function/class.
If you have this template function:
template<typename T>
void Stuff(T &t)
{
t.call(15);
}
There is an implicit requirement on T
. This requirement is that it has a member function called call
. There must be a single overload of this member function which can be called with an integer value.
This means that any type that happens to fit this prototype can be used.
Template polymorphism is more broad than inheritance polymorphism, because it can be used by a broader array of types. A type has to be designed specifically to use inheritance polymorphism; you have to derive from a class. A type can be non-destructively (ie: you don't have to change the type itself) adapted to template polymorphism. Even moreso if your template prototype is well designed:
template<typename T>
void Stuff(T &t)
{
call(t, 15);
}
All that this version of Stuff
requires is that there is some function that takes a T&
and an integer value. If I have some type that I want to use with Stuff
, all I have to do is define a call
function in an appropriate namespace (namely, the namespace that the type was defined in). And this will work just fine. All without modifying the type itself.
Of course, compile-time polymorphism is... compile-time. If I want some user input or data file to select the polymorphic type, templates aren't going to help a whole lot (though type erasure, a template-based technique, can help). The principle benefit of runtime polymorphism is that it is indeed runtime.
Another benefit is that it is more precise about its prototypes. Everything is explicitly stated about inheritance. The virtual function interface in a base class is clearly laid out. The compiler will stop you from attempting to use that base class incorrectly (calling methods that don't exist on it). Indeed, a decent IDE will guide your code so that you will only see the methods on the base class.
Template polymorphism is a lot more implicit. Since C++ has no way of spelling out the prototype that a particular template function/class puts on a type, it's very easy to accidentally call something on a template type that you shouldn't. The compiler will only detect this when you try to use a type that doesn't fit the prototype. And even then you will generally get a massive error spew (depending on how deeply nested your template code is) that makes it difficult to know where the problem is.
It's also a lot harder to implement the implicit template polymorphic prototype, since it isn't spelled out. Implementing a derived class requires walking through the base class, looking at all of the virtual functions, and implementing them. Doing this for a template prototype is much more difficult, unless there is documentation somewhere that spells it out. If you fail to implement something, you again get an error spew that is generally less than forthcoming about the problem.

- 449,505
- 63
- 781
- 982
-
1"There must be a single overload of this member function which can be called with an integer value." -- and that call with `int` must not be ambiguous, and possibly some other condition that I've forgotten. That's why the polymorphic prototype is usually documented in terms of "this expression must have the following properties: ... ". If you try to document it in terms of which functions and overloads *exist* then you get into all sorts of edge cases. – Steve Jessop May 11 '12 at 18:12
-
They know what polymorphism / templates are. Clearly you can choose to do things with templates, which would mean your app would need to generate C++ code and re-compile so be bundled with a compiler (depending on what you're doing). With polymorphism, everything could be done at run-time without restarting or recompiling the application. There is a definite similarity between the two things. I'm currently deciding whether I should do things with templates or with parameters to constructors (in a polymorphic way). I think because I want extensions to be coded in C++, I'll use template. – MathCrackExchange Aug 23 '22 at 00:31
-
On the other hand, if the number of ways of configuring something is infinite, probably polymorphism is the best way to go. Take `Category
` vs `Category(Objects, Morphisms)`. I think because you can have any finite set as the collection of objects, I should instead code things using polymorphism, and only use templates where they can reduce the coding load. – MathCrackExchange Aug 23 '22 at 00:35 -
1@Prime: "*They know what polymorphism / templates are.*" The whole point of my post is that "polymorphism" also includes certain uses of templates. It isn't *runtime* polymorphism, but it is all just different forms of polymorphism. – Nicol Bolas Aug 23 '22 at 00:43
In a nutshell, it comes down to the outcome of your commonality-and-variability analysis of the problem to be solved.
If you're doing the same operations on different stuff, then you would use templates e.g. List<int>
and List<float>
If you're doing the same operations in different ways on the same stuff according to the context, which also has some commonality, then you would use polymorphism e.g. the AbstractInterface::openFile
interface with the derivatives WindowsInterface::openFile
and LinuxInterface::openFile
, one of which would be used according to the context. The abstract interface identifies the commonality of the fact that the same operation is being done conceptually, the derivatives fulfil the variability of the implementation of the concept.

- 2,395
- 1
- 22
- 17