This is exactly what inheritance is for. You create a common, non-template, pure-virtual base class that defines the interface used by all of your templates, e.g.:
class Base {
public:
virtual ~Base() {};
virtual void foo() = 0;
virtual int bar(int param) = 0;
// Etc, for whatever other methods you want
};
Then you derive your template from it:
template<int dim, typename typ>
class Dervied : public Base
{
public:
virtual ~Derived();
virtual void foo();
virtual int bar(int param);
// Etc, for whatever other methods you want
private:
std::vector<typ> data;
};
And of course implement the methods for the Derived
template. Then you can access any instantiation of Derived
through a pointer or reference to Base
. For example:
void callFoo(const Base& b)
{
b.foo();
}
int main()
{
Derived<3,float> d_f3;
Derived<2,double> d_d2;
callFoo(d_f3);
callFoo(d_d2);
return 0;
}
It sounds from your description like there may be some methods that are in common among all instantiations of Derived
, but some that are dependent on template parameters, e.g.
void addNumber(typ number);
In this case, you can't pull this function up into Base
, since it wouldn't make sense to call this method on a Derived<n,float>
. If there are some functions that are dependent on type and some that are dependent on the number, then you could create base classes encapsulating those ideas, like this:
class Base
{ /* All methods independent of template parameters */ };
template <int dim> DimBase : virtual public Base
{ /* All methods dependent only on the dimension parameter */ };
template <typename typ> TypBase : virtual public Base
{ /* All methods dependent only on the type parameter */ };
template<int dim, typename typ>
Derived : public DimBase<dim>, public TypBase<typ>
{ /* All methods */ };
This will allow you to call any independent method using a Base
pointer or reference, to call any dimension-dependent method using a DimBase<n>
pointer or reference, and any type-dependent method using a TypBase<T>
pointer or reference.
Note that in the above, it is advisable that Base
, TypBase
and DimBase
all be abstract classes (containing at least one unimplemented virtual method), and it is essential that TypBase
and DimBase
inherit from Base
using virtual public
instead of just public
, otherwise you get the "dreaded diamond"