it's an interesting question, but unfortunately, it's a brain**** due to differing paradigms
usually,
dynamic polymorphism is for sharing an interface with different implementations
from the caller's POV, you have the
same base and function call, but lots of
different behavior
whereas a
template is for sharing same implementations to avoid copy-pasting code
from the caller's POV, you have a
different type, but the
same behavior/algorithm
so their uses tend to be orthogonal with each other
----------------------------------------
template typing is, in a sense,
stricter than dynamic polymorphism so you will have problems implementing a heterogenous array like you have above in your example
one way around this is to use boost/bind and boost/function to abstract away this strictness using lambda calculus
warning: it ain't very pretty (looks like 1 part template 3 part boost):
output:
rectangle
rect area
triangle
tri area |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
template<typename T>
void DrawShape( const T& t )
{
t.draw();
t.area();
}
void DrawIt( boost::function<void()> fn )
{
fn();
}
class rectangle
{
public:
void draw() const {std::cout<<"rectangle\n";}
void area() const {std::cout<<"rect area\n";}
};
class triangle
{
public:
void draw() const {std::cout<<"triangle\n";}
void area() const {std::cout<<"tri area\n";}
};
int main()
{
rectangle recta;
triangle tri;
vector< boost::function<void()> > v;
v.push_back( boost::bind( DrawShape<rectangle>, recta ));
v.push_back( boost::bind( DrawShape<triangle>, tri ));
for_each( v.begin(), v.end(), DrawIt );
return 0;
}
|
edit: I realize now that this is almost faking it, because you can replace the code above with boost::bind and boost::function and not use any templates at all!
as I mentioned before, the headache with your example is a dissonance caused by template's strict typing requirements and your use of a heterogenous array
edit: I take that back - since boost::bind and boost::function are totally using templates anyways, you are, indeed, using templates underneath (sorry, brain turning mushy at 4AM)
but it holds true that I can remove templates from the example posted above and just use the templates inside boost's implementation