views:

38

answers:

1

My main project class is templated class, declared with:

template<int dim, typename typ>

where dim is number of dimensions (2 or 3), and typ is floating point data type (float or double). Based on these parameters, instances of this class have their members of specific type and vectors (math) have dim number of components.

So instances can differ on member types, and their functions differ on parameter types, but they all have the same function arrangement... what can be made to run-time i.e. generically access functions of instances of this class created with different template arguments ???

+3  A: 

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"

Tyler McHenry
Tyler thank you for the answer. Simple inheritance is not a problem, the biggest problem I have are function parameters that depend on dimension and type e.g. vec<dim,typ>. What about them ?
Fic Firic
The second part of my answer addresses how you can get polymorphic behavior for methods that depend on either dimension or type. Methods that depend on *both* dimension and type must be defined in the leaf class and cannot be used polymorphically. Think about it: if the arguments to a method depend on both the dimension and the type of a class, how could you expect to call that same method on an object of a class with different dimension and type? Such a thing wouldn't make any sense.
Tyler McHenry