You've claimed that with templates "nothing of there is as simple to use as
virtual functions", which is quite an emphatic assertion on the alleged
difficulty of using templates.
Can you somehow be more specific in your complaint. "nothing is as simple"
means that "everything is more complex". That was exactly what I meant.
Ages of practice of helping newcomers to gain skill with one or other
are shown that it is so. Several even fear to use mundane templates
like the ones in standard library and try to write their own ByteBuffer
Do you believe that the example I've
provided is harder to use than an equivalent one you can come up based on
inheritance?
My main() did look really desolate and simple so I think that usage
indeed was easier. Both 'virtual' and 'override' were added to ProductA and
ProductB members just to document indent and may be removed by language
rules. So there remains just declaration of required interface that is great
to have.
The gang of four book on design patterns refers to the strategy pattern also
as the policy pattern. The wikipedia article as well. But in this context,
as we are discussing the generic programming implementation, it's more
appropriate to call it by its name, the policy pattern, due to the chapter
on policy-based design that Andrei Alexandrescu wrote in his «Modern C++
design: generic programming and design patterns applied" book.
Ok, some sort of contradicting terminology. Better implement real policy
pattern with template and lets compare?
The example was supposed to be concise and to avoid implementing any
algorithm. If you believe it's relevant to the discussion, rename
"Product(A|B)" to, for example, "ConcreteStrategy(HTML|LaTeX)", tweak the
member functions to output the appropriate preamble, header and document
bodies, rename "ProductOverviewPolicy" to "DocumentOutputPolicy", and tweak
its output() member function as appropriate.
Names impress me not. I was about effect achieved. Effect that your code
achieved felt too trivial.
Every single bit of it. You just snipped it.
You had to clutter the source code with an extra class
declaration, you were forced to sprinkle pure virtual functions around, and
there are override directives everywhere. How did you make that example any
simpler by adding all that unnecessary cruft?
Lets see your complaints.
1) "extra class" is *the* interface specification. In your example
interface was nowhere specified. So why it was easier?
2) "pure virtual" means that if you want to have the interface you must
override it. '=0' is oh so hard to type?
3) "override" means that it implements or overrides base class
implementation. That results with compile time error if interface
is tiniest bit different in derived class. Try edit IOverView:
'virtual std::string name() const {return "";}'
It is making everything very safe and novice-friendly. 8 characters.
4) I also had redundant 'virtual' in overrides, why you did not complain,
another 7 characters? It just feels more readable and safe, both
'override' and 'virtual' may be removed from overrides by language
rules.
The generic programming solution achieves the exact same objective, and is
far cleaner, easier to read, and straight-forward.
Food for thought.
Shrug. I still do not understand your objective. If it was to have:
ProductOveviewPolicy<ProductB> overview_b;
overview_b.output(B);
.... instead of:
output(B);
.... then that feels not simpler to me. If it was to get error messages
about interface differences somewhere inside of alien template instead
of point of declaration then that feels also not simpler for me.
I feel that you just want to argue. There is nothing to argue, I said
what I meant and even your own example feels to support mine points
better than yours. Dynamic polymorphism is often actually needed,
it can be used elegantly for doing lot of things for what it is not
actually needed and it seems to be easier to learn for novices than
template metaprogramming.