I need to Understand that whether really Inheritance & virtual functions
not necessary in C++ and one can achieve everything using Generic programming
. This came from Alexander Stepanov
and Lecture I was watching is Alexander Stepanov: STL and Its Design Principles
-
10I don't understand your comment. The question is about why should we use inheritance if *generic programming* is more powerful and achieves the same goal. – Antoine Nov 04 '11 at 13:00
-
2I think this is a great question. +1 to both the question and Antoine. – avakar Nov 04 '11 at 13:03
-
2@KerrekSB Its much too easy to dismiss a question with a knee jerk reaction rather than too think about it. This is a good question and worth thinking about. Generic programming is not primitive and likening it to goto vs for loops is not a fair at all. – anio Nov 04 '11 at 13:12
-
2@anio: Nonetheless the question is a short-sighted one that misses the point that C++ is a powerful, general-purpose, multi-paradigm language. Once you appreciate that it lets you design `std::shared_ptr` and `boost::any`, you would be less quick to ask for an entire part of it to be chopped off. – Kerrek SB Nov 04 '11 at 13:14
-
At the first moment I cannot see how generic programming (specicifically C++ templates) could achieve runtime polymorphism. Although that's of course not always needed, but still the most prominent feature of OO and its IMHO advantage over templates (which in turn have other advantages). But I'm by no means a template magician (not yet) and maybe I see things too narrow. And of course Kerrek's perspective is also nice. – Christian Rau Nov 04 '11 at 13:19
-
4I haven't watches Stepanov's talk yet (though I will, always nice to hear someone brilliant), but here's a thought: Back in 1994, templates hardly existed at all, and everyone was jumping on the "object-oriented" bandwagon (perhaps the "Object Oriental Express"?), culminating in that fatal 5am decision that "the world needs Java". So undoubtedly people were abusing and misunderstanding the ideas of object orientation at the time, and Stepanov's crucial realisation was that a lot of programming is "generic" rather than "polymorphic" (think sorting). That was undoubtedly an extremely... – Kerrek SB Nov 04 '11 at 13:35
-
3... valuable insight. But that alone doesn't mean that you can simply *replace* one technique with another. It just means that a lot of problems are better expressed as generic ones rather than polymorphic ones. We gained an immensely powerful tool in the toolbox. But that doesn't mean we can throw the other tools away. – Kerrek SB Nov 04 '11 at 13:37
-
Update: I *have* now watched the talk and would like to point out the line "when done right, inheritance is a wonderful thing", and many further such points which are entirely in line with my previous comment. I'm now tempted to say that the OP has somewhat missed the point of the talk. – Kerrek SB Nov 04 '11 at 15:47
5 Answers
I always like to think of templates and inheritance as two orthogonal concepts, in the very literal sense: To me, inheritance goes "vertically", starting with a base class at the top and going "down" to more and more derived classes. Every (publically) derived class is a base class in terms of its interface: A poodle is a dog is an animal.
On the other hand, templates go "horizontal": Each instance of a template has the same formal code content, but two distinct instances are entirely separate, unrelated pieces that run in "parallel" and don't see each other. Sorting an array of integers is formally the same as sorting an array of floats, but an array of integers is not at all related to an array of floats.
Since these two concepts are entirely orthogonal, their application is, too. Sure, you can contrive situations in which you could replace one by another, but when done idiomatically, both template (generic) programming and inheritance (polymorphic) programming are independent techniques that both have their place.
Inheritance is about making an abstract concept more and more concrete by adding details. Generic programming is essentially code generation.
As my favourite example, let me mention how the two technologies come together beautifully in a popular implementation of type erasure: A single handler class holds a private polymorphic pointer-to-base of an abstract container class, and the concrete, derived container class is determined a templated type-deducing constructor. We use template code generation to create an arbitrary family of derived classes:
// internal helper base
class TEBase { /* ... */ };
// internal helper derived TEMPLATE class (unbounded family!)
template <typename T> class TEImpl : public TEBase { /* ... */ }
// single public interface class
class TE
{
TEBase * impl;
public:
// "infinitely many" constructors:
template <typename T> TE(const T & x) : impl(new TEImpl<T>(x)) { }
// ...
};

- 464,522
- 92
- 875
- 1,084
They serve different purpose. Generic programming (at least in C++) is about compile time polymorphisim, and virtual functions about run-time polymorphisim.
If the choice of the concrete type depends on user's input, you really need runtime polymorphisim - templates won't help you.

- 24,346
- 3
- 50
- 88
-
As I tried to point out in my answer, you **can** use templates in your *runtime polymorphism* case, but it will lead to unmaintainably bloated if/else branches. – bitmask Nov 04 '11 at 13:19
Polymorphism (i.e. dynamic binding) is crucial for decisions that are based on runtime data. Generic data structures are great but they are limited.
Example: Consider an event handler for a discrete event simulator: It is very cheap (in terms of programming effort) to implement this with a pure virtual function, but is verbose and quite inflexible if done purely with templated classes.
As rule of thumb: If you find yourself switching (or if-else-ing) on the value of some input object, and performing different actions depending on its value, there might exist a better (in the sense of maintainability) solution with dynamic binding.
Some time ago I thought about a similar question and I can only dream about giving you such a great answer I received. Perhaps this is helpful: interface paradigm performance (dynamic binding vs. generic programming)
It seems like a very academic question, like with most things in life there are lots of ways to do things and in the case of C++ you have a number of ways to solve things. There is no need to have an XOR attitude to things.

- 35,813
- 6
- 60
- 86
In the ideal world, you would use templates for static polymorphism to give you the best possible performance in instances where the type is not determined by user input.
The reality is that templates force most of your code into headers and this has the consequence of exploding your compile times.
I have done some heavy generic programming leveraging static polymorphism to implement a generic RPC library (https://github.com/bytemaster/mace (rpc_static_poly branch) ). In this instance the protocol (JSON-RPC, the transport (TCP/UDP/Stream/etc), and the types) are all known at compile time so there is no reason to do a vtable dispatch... or is there?
When I run the code through the pre-processor for a single.cpp it results in 250,000 lines and takes 30+ seconds to compile a single object file. I implemented 'identical' functionality in Java and C# and it compiles in about a second.
Almost every stl or boost header you include adds thousands or 10's of thousands of lines of code that must be processed per-object-file, most of it redundant.
Do compile times matter? In most cases they have a more significant impact on the final product than 'maximally optimized vtable elimination'. The reason being that every 'bug' requires a 'try fix, compile, test' cycle and if each cycle takes 30+ seconds development slows to a crawl (note motivation for Google's go language).
After spending a few days with java and C# I decided that I needed to 're-think' my approach to C++. There is no reason a C++ program should compile much slower than the underlying C that would implement the same function.
I now opt for runtime polymorphism unless profiling shows that the bottleneck is in vtable dispatches. I now use templates to provide 'just-in-time' polymorphism and type-safe interface on top of the underlying object which deals with 'void*' or an abstract base class. In this way users need not derive from my 'interfaces' and still have the 'feel' of generic programming, but they get the benefit of fast compile times. If performance becomes an issue then the generic code can be replaced with static polymorphism.
The results are dramatic, compile times have fallen from 30+ seconds to about a second. The post-preprocessor source code is now a couple thousand lines instead of 250,000 lines.
On the other side of the discussion, I was developing a library of 'drivers' for a set of similar but slightly different embedded devices. In this instance the embedded device had little room for 'extra code' and no use for 'vtable' dispatch. With C our only option was 'separate object files' or runtime 'polymorphism' via function pointers. Using generic programming and static polymorphism we were able to create maintainable software that ran faster than anything we could produce in C.

- 572
- 2
- 5