Search code examples
c++templatestemplate-templates

Template Class that takes a Template Class that Takes a Concrete Class


While I've seen a few posts regarding taking in template classes as a parameter into a template class I can't seem to find something that works with my code, or simply I do not understand the explanation well enough.

Ultimately, I'm looking for a template class that takes another template class which takes a standard class.

*Note: For brevity, I've only included what I believe to be sufficient information.

I've made an attempt based on the information I could find and it is shown here:

Concrete Class

class ConcreteClass {
   private:
      std::string words;
   public:
      ConcreteClass(std::string newWords);
};
#endif

Template Class template

template <class ConcreteClass>
class TemplateClass{
   private:
     ConcreteClass stuff;
   public:
     TemplateClass(ConcreteClass fillStuff);
};

#endif


template <class ConcreteClass>
TemplateClass<ConcreteClass>::TemplateClass(ConcreteClass fillStuff) {
     stuff = fillStuff;
}

Base Class template


template<template<class> ConcreteClass, class TemplateClass>
class BaseClass {
   private:
     TemplateClass<ConcreteClass>* objPntr;
}

template<template<class> ConcreteClass, class TemplateClass>
BaseClass<TemplateClass<ConcreteClass>::BaseClass(TemplateClass<ConcreteClass>* newObj) {
    objPntr = newObj;
}
template<template<class> ConcreteClass, class TemplateClass>
BaseClass<TemplateClass<ConcreteClass>::~BaseClass() {
   if(objPntr) {
      delete objPntr;
    }
}

Main

int main() {
   ConcreteClass cClass("some values");
   TemplateClass tClass(cClass);
   BaseClass(tClass);

   return 0;
}

Solution

  • Firstly, you need a class or typename keyword before the template parameter name in the case of template-templates. Secondly, you should put the template<class> before TemplateClass, not ConcreteClass. TemplateClass is your templated type, so it needs that specifier:

    #include <string>
    
    // I had to make up your types because there is no definition for them
    struct ConcreteClass {
        std::string value;
    };
    
    template <typename T>
    struct TemplateClass {
        T t;
    };
    
    template<class ConcreteClass, template<class> class TemplateClass>
    class BaseClass {
       private:
         TemplateClass<ConcreteClass>* objPntr;
    
    // constructor needs to be declared before being defined
    public:
         BaseClass(TemplateClass<ConcreteClass> *objPntr);
    };
    
    template<class ConcreteClass, template<class> class TemplateClass>
    BaseClass<ConcreteClass, TemplateClass>::BaseClass(TemplateClass<ConcreteClass>* newObj) {
        objPntr = newObj;
    }
    
    int main() {
       ConcreteClass cClass{"some values"};
       TemplateClass<ConcreteClass> tClass{cClass};
       BaseClass<ConcreteClass, TemplateClass> bClass(&tClass);
    }