Introduction
In this brief article we’ll have a look at the topic of building template classes whose parameters are themselves templates.
I’m assuming you’re reasonably familiar with template classes. If not, here’s a quick introduction.
The problem
Let’s start with a case study. Suppose we want to build a simple hash table class. Our class should be generic for different types of keys and values*. Obviously, it should be a template class.
We might want to add more flexibility to our design by allowing the client to choose the type of container class used by the SimpleHashTable to store its keys and values (for example, for performance reasons we may want to use a fixed-size container)
We need to add the container class as a template parameter. However, a container class is typically a template class itself.
Let’s modify the SimpleHashTable to allow the container type to be specified:
We must tell the compiler that the template parameter Container_Type is itself a template class. Notice that the template parameter for the template class must not match any of the other identifiers in the template list.
The Container_Type parameter is used to instantiate a new container within the SimpleHashTable, whose template parameter is one of the template parameters supplied to the SimpleHashTable. In other words, there is a ‘cascading’ of template parameters within the class: a parameter supplied to the owning template is used to instantiate a nested template class within.
Let’s have a look at what gets created when we instantiate our SimpleHashtable class:
As with all template parameters, template-template parameters can be defaulted (the usual rules for defaults apply). Note, however, that the template default must be a template class.
Summary
Once we start building template classes it becomes natural to incorporate them into other, more complex, template classes. The aim is to build our generic code with as much flexibility as possible.
*This is a deliberately artificial example. You wouldn’t implement a hash table this way, typically; and you don’t need to since one is supplied with the Standard Library.
- Practice makes perfect, part 3 – Idiomatic kata - February 27, 2020
- Practice makes perfect, part 2– foundation kata - February 13, 2020
- Practice makes perfect, part 1 – Code kata - January 30, 2020
Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry.
He specialises in C++, UML, software modelling, Systems Engineering and process development.
Is the use of 'class', rather than 'typename' intentional in these examples? In every other article you exclusively use typename.
Great set of articles btw.
class is used because template template parameters can only be classes. This is not just for emphasis but is the rule.
Yes, this is the rule, but it should be possible to use both template and class keywords in c++17.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html
In your example "Template parameter is a template class" should actually be written as "Template parameter is a class template". This slight inversion of order makes a total difference (check the C++ Standard for example). Your other example "Default (must be a template class) is correct, since in this case you're really pointing to a instantiation of a class template.
Wanted to point out that using template of template here is not only useless, but is unnecessarily restrictive. In your case simple "class Container_Type" would do. Otherwise container is restricted to a class with a single argument, not more, not less.
There surely are cases where template of template is useful and even necessary, but this example as it is written is not one of them )
Pingback: C++ Template of template | Heresy's Space
Another tough concept explained nicely without hiccups..
Pingback: Overload operator for both std::vector and std::list | Developer FAQs
Wondering about debugging (which is already difficult on embedded systems)...do we loose any flexibility in later stages, such as debugging?
Pingback: How to do compile-time recursion over a given set of template template classes? – Windows Questions