I have multiple factories, each is responsible for creating instances of an inheritance tree. For example (syntax or semantics maybe incorrect),

struct InterfaceA {};  struct ImplA1 : InterfaceA {}; ... 
struct FactoryA { vector<InterfaceA*> create(); }    
... // (repeat for B, C, etc)

foo is template class

template<ATy, BTy, ..>
struct foo {
     // default behavior - no functionality

foo is specialized for some combination of subclasses of InterfaceA, InterfaceB, and ...

struct foo<ImplA1, ImplB2, ..> {
     void feature1();
     void feature2();

Is it possible to combine the inheritance hierarchies with the template class? i.e.

void bar(vector<InterfaceA*> vecA, vector<InterfaceB*> vecB, ..) {
    foo< /* what to put in here */ >(vecA.front(), vecB.front(), ...) f;
    f.feature1();  // if specialization not there, complain

I can use Curiously Recurring Template Pattern (CRTP) for one tree. Not sure how to get it work with multi trees.

  • 2
    I'm not sure what problem you're trying to solve. The static types of vecA.front() and vecB.front() are clearly known. And if you need to instantiate a template based on their dynamic type – well, you can't do that… – 5gon12eder May 18 '16 at 20:49
  • vecA.front() is InterfaceA*? – Candy Chiu May 18 '16 at 21:10
  • @CandyChiu: Yes, vecA.front() returns an item of type InterfaceA*. It can point to an ImplA1, ImplA2 or any other derived class of InterfaceA. – Bart van Ingen Schenau May 19 '16 at 9:08
  • Yes, so in template resolution, it won't select the specialized. – Candy Chiu May 19 '16 at 13:08

Seems what you want is:

void bar(vector<InterfaceA*> vecA, vector<InterfaceB*> vecB) {
    // If InterfaceA == ImplA1 && InterfaceB == ImplB2 then:
    foo<ImplA1, ImplB2> f(*dynamic_cast<const ImplA1*>(vecA.front()), *dynamic_cast<const ImplB2*>(vecB.front()));
    // ...
    f.feature1();  // if specialization not there, complain

which is not possibly, because the template instantiation is a compile-time thing and you want to make a decision on a dynamic run time type. (Btw. Even above only works if you give InterfaceA|B a virtual d'tor.)

So from your comment // if spec not there, complain I can state this:

  • You cannot complain at compile time, because the decision to make is based on run time information
  • You could write a runtime dispatcher that selects the correct template instantiation (or fails with e.g. an exception) at run time: How to do that is another story, possibly best asked over at SO.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.