views:

98

answers:

2

I have a hierarchy of class templates. At the top of the hierarchy is an abstract base class (interface). I won't know which concrete implementation to instantiate until runtime, so it seems like the perfect situation to use the factory pattern. However, virtual member function templates are not allowed in C++.

How can I achieve a legal design similar to the below in C++?

The individual concrete implementations of the IProduct interface as well as the concrete factories will live in different dynamic libraries, one or more of which will be loaded at runtime.

template<class T> class IProduct
{
public:
   virtual void doWork(const T & data) = 0;
};

template<class T> class ProductA : public IProduct<T> {/*...*/};
template<class T> class ProductB : public IProduct<T> {/*...*/};

class IProductFactory
{
public:
   template<class T> virtual IProduct<T> * createProduct() = 0;
};

class ProductAFactory: public IProductFactory
{
public:
   template<class T> virtual IProduct<T> * createProduct()
   {
      return new ProductA<T>;
   }
};

class ProductBFactory: public IProductFactory
{
public:
   template<class T> virtual IProduct<T> * createProduct()
   {
      return new ProductB<T>;
   }
};
+3  A: 

Why can't you templatize IProductFactory on T as well? That would get rid of your error, and it's no less general. The client is still going to have to know what T is in order to call thecreateProduct method.

Edit Re: comment

In order to do this, you will need to just create a templatized function to create the factory. So:

template<class T> IProductFactory<T>* getProductFactory();

Now your factory is templatized, the createProduct method is no longer a member template. Not sure what your criteria is for returning a ProductAFactory vs. a ProductBFactory but you will either have to pass in a string to choose, have this be a member function of another class that would make the decision, or have multiple free functions but only expose one version or another to a particular client.

bshields
Yep, that's the only meaningful solution here.
Nikolai N Fetissov
I thought of that too, but isn't that just pushing the problem up to a higher level class? Consider a client that wants to make a IProduct<Foo>. The client still needs to get an appropriate concrete IProductFactory<Foo>, which means there needs to be something that can polymorphically create IProductFactory<T>. Am I missing something?
Nick Meyer
A: 

This doesn't need a template. Does that eliminate your problem?

Jay
Please elaborate... how do I eliminate the template parameter from the design?
Nick Meyer