Friday, January 17, 2014

c++ template template parameters

c++ template template parameters : templates tutorial
It can be useful to allow a template parameter itself to be a class template. Again, our stack class template can be used as an example.
To use a different internal container for stacks, the application programmer has to specify the element type twice. Thus, to specify the type of the internal container, you have to pass the type of the container and the type of its elements again:

Using template template parameters allows you to declare the Stack class template by specifying the type of the container without respecifying the type of its elements:

To do this you must specify the second template parameter as a template template parameter. In principle, this looks as follows:
There is a problem with this version that we explain in a minute. However, this problem affects only the default value std::deque. Thus, we can illustrate the general features of template template parameters with this example.

The difference is that the second template parameter is declared as being a class template:

The default value has changed from std::deque<T> to std::deque. This parameter has to be a class template, which is instantiated for the type that is passed as the first template parameter:

This use of the first template parameter for the instantiation of the second template parameter is particular to this example. In general, you can instantiate a template template parameter with any type inside a class template.
As usual, instead of typename you could use the keyword class for template parameters. However, CONT is used to define a class and must be declared by using the keyword class. Thus, the following is fine:

but the following is not:

Because the template parameter of the template template parameter is not used, you can omit its name:

Member functions must be modified accordingly. Thus, you have to specify the second template parameter as the template template parameter. The same applies to the implementation of the member function. The push() member function, for example, is implemented as follows:

Template template parameters for function templates are not allowed.

Template Template Argument Matching

If you try to use the new version of Stack, you get an error message saying that the default value std::deque is not compatible with the template template parameter CONT. The problem is that a template template argument must be a template with parameters that exactly match the parameters of the template template parameter it substitutes. Default template arguments of template template arguments are not considered, so that a match cannot be achieved by leaving out arguments that have default values.
The problem in this example is that the std::deque template of the standard library has more than one parameter: The second parameter (which describes a so-called allocator) has a default value, but this is not considered when matching std::deque to the CONT parameter.
There is a workaround, however. We can rewrite the class declaration so that the CONT parameter expects containers with two template parameters:

Again, you can omit ALLOC because it is not used.
The final version of our Stack template (including member templates for assignments of stacks of different element types) now looks as follows:

The following program uses all features of this final version:

Note that template template parameters are one of the most recent features required for compilers to conform to the standard. Thus, this program is a good evaluation of the conformity of your compiler regarding template features.

See Also:


No comments:

Post a Comment