Home > Enterprise >  c - passing standard container as a template template parameter
c - passing standard container as a template template parameter

Time:09-16

So, I need to make a mixin class that would encapsulate children of some derived class. The derived class should inherit from the mixin while providing a container template as a template template argument for the mixin.

The desired code is somewhat like that:

/*template definition*/
template<template<typename T, typename A> class C>
class HasChildren {
  protected:
    C<T, A> m_children;
    /* whatever */
};
 

It has an array of issues:

  1. When trying to instantiate this class like HasChildren<std::vector<int>>(just for testing), compiler says expected a class template, got ‘std::vector<int>’. Clearly, I'm not passing a template template. I would like to know what exactly I'm trying to pass.
  2. For C<T, A> m_children; compiler says that T and A are out of scope. When I add typename keyword for them, the error changes to error: wrong number of template arguments (1, should be 2). I would like to know why T and A are out of scope and why adding typename leads to this error.

CodePudding user response:

  1. You pass a type, std::vector<int>, instead of a template, std::vector.
  2. You need to accept the template template parameters too. template<typename T, typename A> does not make the template template use T and A. They are just for documentation and can be removed.

Example:

template <template <class, class> class C, class T, class A>
//                                         ^^^^^^^  ^^^^^^^
class HasChildren {
   protected:
    C<T, A> m_children;
};

int main() {
    HasChildren<std::vector, int, std::allocator<int>> hc;
//              ^template^   ^-----parameters-------^
}

If you prefer to instantiate HasChildren like you originally tried, by using HasChildren<std::vector<int>>, you can do that by specializing HasChildren:

template<class> class HasChildren; // primary

// specialization:
template<template <class, class> class C, class T, class A>
class HasChildren<C<T,A>> {
   protected:
    C<T,A> m_children;
};

int main() {
    HasChildren<std::vector<int>> hc; 
}
  • Related