8

I want to start this question by saying that it is paradigm-related and that I am only trying to clarify some concepts. So I have been programming in Python for about 2 years now, dipped my toes into Java but not too much and I want to delve into C++. I've used it before but not for large projects with a lot of design involved.

When I first started explored it I believed that it addressed OOP similarly to Java where everything has to implement an interface. Then I bumped into the concept of templates which I immediately though to be a workaround to provide polymorphic behaviour to primitives(ints, floats) which did not implement it(basically what Python did through duck-typing and no formal interfaces). But I soon discovered that templates were used to provide the same behaviour to non-primitive types.

So my question is: what reason is there to use classic polymorphism over templates, and what is the general approach to this in the C++ community?

EDIT Just found this which pretty much answers the question(static polymorphism really need to wrap my head around this terminology).

Community
  • 1
  • 1
nikitautiu
  • 951
  • 1
  • 14
  • 28
  • 3
    Templates work their magic at compile time (and therefore everything related must also be known at compile time), polymorphism at runtime. There is no overlap. Different tools for different jobs. – Jon Nov 19 '12 at 16:04
  • 1
    Exactly, that's what I want clarified. How do I choose between either a function f(SomeInterface x) vs the templated one f(T x) where T is an object with an unspoken interface(duck-typeish)? – nikitautiu Nov 19 '12 at 16:14
  • Toss a coin. I'll note that in GCC-land, errors arising from template code tend to be quite painful to read. – Rook Nov 19 '12 at 16:19
  • @vitiv: What would `SomeInterface` be in the non-templated version if you want `x` to be duck-typed? – Jon Nov 19 '12 at 16:22
  • @Jon: as in the first one `x` implements `SomeInterface` with let's say method `foobar` and in the templated version we ignore that it implements whatever interface and just call `foobar` – nikitautiu Nov 19 '12 at 16:25

1 Answers1

8

At the risk of making sweeping generalizations, templates are mostly used similarly to Generics in Java - they allow you to build a class or function that can be used with many different data types. Take std::list, part of the Standard Template Library. You can make a linked list of integers with std::list<int>, or a list of objects with std::list<MyClass>. Another example is std::thread, which uses templates to take a function (or lambda or functor) and its arguments to run in another thread.

As for choosing between a function f(SomeInterface x) and a function template f(T x), it really depends on context and is somewhat subjective. Some things to take into consideration are:

  • Function templates and class templates are resolved at compile time, so you may get better performance. However,

  • C++ compilers historically generate barely-descipherable garbage for template errors. Clang has done some work to improve this, and other compilers are getting better in an effort to match Clang. Things are getting better, but it's still pretty ugly.

  • Don't be afraid to use traditional polymorphism with interfaces and implementation classes. While templates are used instead of of polymorphism in some cases (see C++'s std::thread which uses templates vs. Java's Thread which uses a Runnable interface), polymorphism is still extremely common in C++ libraries and projects.

In short, feel free to consider using templates, but don't look at them as a replacement for polymorphism. Look at a popular C++ library and you're bound to find plenty of polymorphism. Take OGRE, a popular C++ graphics engine. If you look at its class list, you'll find lots of interfaces (such as WindowEventListener and FrameListener) which the user can derive a class from in order to interact with the library.

Matt Kline
  • 10,149
  • 7
  • 50
  • 87
  • Good explanation. Now I am more curious about guidelines or common practices of when to use which, considering the "subjective" disclaimer. – nikitautiu Nov 19 '12 at 16:36
  • To be honest, I haven't seen templates used instead of polymorphism very much outside the C++ Standard Library. I've updated my answer accordingly. – Matt Kline Nov 19 '12 at 16:44
  • Thanks, really insightful. To be honest: I hoped that using interfaces was the answer. They feel more natural, so I guess I'll restrict my usage off templates to generics(doing Java in C++..heh). – nikitautiu Nov 19 '12 at 16:52