Ok. Actually, I was even considering such total pigsties as a try-catch statement using the catch blocks to infer the type. But this is actually not the point. The solution needs to scale when you start using more instantiations of the template.
To this end, this is what I could think of so far:
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
|
#include <iostream>
#include <typeinfo>
#include <memory>
struct Base {
virtual ~Base() {}
};
struct IHasFunction
{
private:
virtual void f() = 0;
protected:
virtual ~IHasFunction() {}
friend bool perform_f(Base *ptr);
};
template <typename T>
struct Derived : Base, public IHasFunction {
void f() { std::cout << typeid(T).name() << std::endl; }
};
bool perform_f(Base* ptr)
{
if(IHasFunction* has_f = dynamic_cast<IHasFunction*>(ptr))
{
has_f->f();
return true;
}
return false;
}
int main()
{
std::auto_ptr<Base> ptr_int(new Derived<int>);
std::auto_ptr<Base> ptr_char(new Derived<char>);
perform_f(ptr_int.get()); //prints i with gcc
perform_f(ptr_char.get()); //prints c with gcc
}
| |
The perform_f function is only proxy I use to increase the encapsulation, because I want to keep the inheritance to IHasFunction private. But that is not strictly necessary, as you may want to access IHasFunction from client code (I assumed otherwise). Also, this introduces multiple inheritance, and may incur slight penalty (I dunno). And the most derived object from Base must derive from IHasFunction only once, which is the worst nasty so far.
All of those problems can be fixed if you do something similar, but instead of using multiple inheritance, derive IHasFunction from Base and derive the generic class only from IHasFunction. Ironically, then IHasFunction will not be just interface. Also, you will need to reintroduce the parametrized constructors from Base into IHasFunction and implement them by simply redirecting them to Base.
EDIT: This latter approach is something like what m4ster r0shi meant:
If the Data class is that general, consider puting an abstract Image class between Data and Image<Pixel,Dim> |
Unfortunately, templates are assumed to have nothing in common regarding their layout. So unless you inherit from some class that anchors them, you can not handle them polymorphically at run-time.
Regards