Be forewarned: This question seems way more obvious than it actually is.
I’d like to write a template that can accept any concrete class or template class as a template parameter. This might seem useless because without knowing whether the passed in T is templated or not you won’t know how to use it. The reason I want this is so that I can declare a general template with no definition, that users then specialize. Because users are specializing it, they always know about the type they’re dealing with. But users can’t specialize a template without it first being declared.
You could do this:
template<class T>
class myclass;
But that won’t work if you pass in a templated T, for example myclass<std::vector> won’t work. So then we try this:
template<class T>
class myclass;
template<template<class> T>
class myclass;
This might be the right track, but it won’t work as is because class templates can’t be overloaded. So let’s switch it to function templates, which can be:
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
Sweet, so we’re done right? Well, there might be different numbers of parameters given to the template template parameter, so we’ll need to take that into account too.
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
template<template<class, class> T>
void myfunc();
template<template<class, class, class> T>
void myfunc();
// etc.
Ugly, but the Boost Preprocessor Library can generate this code for us (and in C++0x support for variadic templates will be added so this ugliness is only temporary). But we’ve still forgotten a case! What if one of T’s parameters isn’t a class, but a constant integer. Lets try to support that:
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
template<template<class, class> T>
void myfunc();
template<template<class, class, class> T>
void myfunc();
// etc.
template<template<class> T>
void myfunc();
template<template<class, int> T>
void myfunc();
template<template<int, class> T>
void myfunc();
template<template<int, class, class> T>
void myfunc();
template<template<class, int, class> T>
void myfunc();
template<template<class, class, int> T>
void myfunc();
// etc.
Uh oh. Given that any constant type can get passed into a template, in any number, mixed with class parameters, KABLOOEY combinatorial explosion. Just to make things more difficult, what if any of T’s parameters are themselves templates?
boost::mpl does something like this (here’s their idea of binding an argument). However, you have to make a lot of assumptions to make it work, like using;
instead of
to not have to offer overloads for all int, char, bool, etc combination.
I can’t think of anything that would be more effective than the boost::mpl approach, and in general, I would think any approach would suffer a lot of problems; a class template is NOT a type, and it can’t really be wedged into the type system that way (boost::mpl treats it as a function to create new types; more generically, it is used to create a “MetaFunction”). I’m not even sure if variadic templates are going to effect template template parameters (interesting question though).