3

I currently use a template class with multiple parameters,

template<class A, class B> class M{ };

However, in the position of class A I want to insert a template class, something like

template<class C> class A{ };

The only solution I've found for doing this is to use template template parameters:

template< template<class C> class A, class B> class M{ };

In my implementation, the only parameterization of A I use is A<B>. I don't need several instantiations of A using different parameters, for example I don't need to instantiate A<int> A<double> and A<long double> in M.

Is there an alternative to the template template parameter? The reason I ask is a follow up of this thread, in which in his answer @Evan Teran says he's only once ever had to use template template parameters...

I guess a twist on my question is: are there downsides to using template template parameters?

Community
  • 1
  • 1
Plamen
  • 650
  • 1
  • 8
  • 27

2 Answers2

2

Assuming B can somehow be determined from A<B>, you can just take one template parameter:

template <class A> class M
{
  typedef typename A::The_B_Type B;
};

Of course, The_B_Type has to be a valid typedef within A<B>. That's one of the reasons why standard library containers provide all the typedefs. For example, if the template A was std::vector, you could do this:

template <class A> class M
{
  typedef typename A::value_type B;
};
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
1

You can take the instantiated A<B> as an argument, then use a traits class to extract the B passed to A<B> if you need it:

template<typename T>
struct extract_b {}; // SFINAE enabled
template<template<class>class A, typename B>
struct extract_b< A<B> > {
  typedef B type;
};

// C++11, you can replace it with typename extract_b<T>::type at point of use
// if you lack support for it:
template <typename T>
using ExtractB = typename extract_b<T>::type;

template<typename A>
struct M {
  typedef ExtractB<A> B;
  // ...
};

the traits class is poorly named, but you can see that I can get the template argument out of A<B> and expose it in M<A>.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Hmmm It seems to rely on me being able to instantiate `A` in advance. If an object of type `A` is a class member of `M`, does this mean I need to use a move/copy constructor? – Plamen Nov 19 '13 at 19:32
  • @plamen instantiate the template amd get a type, not the instance. – Yakk - Adam Nevraumont Nov 19 '13 at 19:52
  • I guess what I'm struggling with is this: how do I instantiate `M` with `A` a template member? This is why I thought template template parameter. – Plamen Nov 19 '13 at 22:46
  • The problem is I'm not using primitive classes. I think this deserves a new question. – Plamen Nov 19 '13 at 22:59