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 promotes the uses of the generic programming and they qualify it as Modern C++ Design.
Here’s what say Andrei Alexandrescu 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 assetions 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.
What the CTaxCalculator class implementation tell 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 Tax.
The CGenericTaxCalculator class in 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 accept only ones graduated from a specific school and reject 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 contains? it must derives from a specific class or not?
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 sound more natural and flexible, and it can provides 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 it’s 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 uses templated libraries.
The Modern C++ design has a preference to the generic programming approach, its 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.