As Bjarne Stroustrup points out, “C++ is a multi-paradigmed language.” It supports many different styles of programs, or paradigms, and object-oriented programming is only one of these. Some of the others are structured programming, and generic programming. In the last few years, C++ experts like Andrei Alexandrescu, Scott Meyers and Herb Sutter promoted the uses of the generic programming and they qualify it as Modern C++ Design.
Here’s what Andrei Alexandrescu says about the Modern C++ design:
Modern C++ Design defines and systematically uses generic components - highly flexible design artifacts that are mixable and matchable to obtain rich behaviors with a small, orthogonal body of code.
Three assertions are interesting in his point of view:
- Modern C++ Design defines and systematically uses generic components
- Highly flexible design
- Obtain rich behaviors with a small, orthogonal body of code
To have a concrete idea about the generics flexibility, let’s compare the implementation of a class calculating a tax in OOP and generic programming.
CTaxCalculator class implementation tells us exactly?
I’m the class
CTaxCalculator, I know how to calculate the tax but I collaborate only with classes of
ICalculator kind. I refuse to colaborate with any other not
ICalculator class even if it can help me to calculate the
CGenericTaxCalculator class on the other side know how to calculate the tax, and for that it can collaborate with any type capable to calculate the tax, and it’s not aware about its kind.
This makes the generic programming more natural and flexible, concerning the first implementation it’s like in the real world, a company searching for a developer accepts only ones graduated from a specific school and rejects all the others even if they have the skills needed.
But the flexibility comes with a price, the code became hard to understand, Indeed in OOP programming I can just go to the definition of
ICalculator to know what we wait for this type. it’s not the case in generic programming, it’s difficult to know what we expect exactly from the template parameter, which members must contain? It must derive from a specific class or not?
It’s true that C++ Traits and SFINAE mechanisms help to defines what we expect from a template param, but it’s an advanced feature and few C++ developers master them.
The C++ designers are aware of this issue, for this reason, many improvements are added to template programming in the new C++ standards, and new ones will come like the interesting feature “Concept-lite” to let define constraints for the template params.
Generic Programming Produce Compact Code
Repeating boilerplate code makes maintenance difficult, and allows all kinds of mistakes. With generic programming, you can avoid harmful repetition.
Let’s take this second minimal example of sum between two numbers.
Here’s an implementation without using templates:
By using a template function, the code became more compact:
It was just a mini sample to show the benefit of using templates to have a compact code, STL and boost contains more advanced algorithm which shows better the power of generic programming to remove the boilerplate code.
But Why the Generic Programming Is Not Widely Used ?
Generic programming sounds more natural and flexible, and it can provide more possibilities than OOP, however many developers found it very complex and difficult to learn and use.
- The code became illisible and hard to maintain.
- The compiler errors are very hard to understand.
Which is confirmed by the design choice of many C++ open source projects, indeed if you take a look in some known C++ source projects, the generic programming is mostly used only in C++ libraries like stl, boost, loki and folly, but very few applications uses the generic approach for their design. however the majority of them use templated libraries.
The Modern C++ design has a preference to the generic programming approach, it is very powerful, but before adopting it you have to be aware of the price to pay. And even there’s a big effort to understand better the generic programming benefits and to simplify their use, thanks to guys like Andrei Alexandrescu, Scott Meyers and Herb Sutter. But the Modern C++ design is not widely adopted yet by the C++ community.