...

/

Understanding Template Parameters

Understanding Template Parameters

Distinguish between various types of template parameters in this lesson.

So far in the course, we have seen multiple examples of templates with one or more parameters. In all these examples, the parameters represented types supplied at instantiation, either explicitly by the user or implicitly by the compiler when it could deduce them. These kinds of parameters are called type template parameters. However, templates can also have non-type template parameters and template template parameters. We’ll explore all of them in this lesson.

Type template parameters

As already mentioned, these are parameters representing types supplied as arguments during the template instantiation. They are introduced either with the typename or the class keyword. There’s no difference between using these two keywords. A type template parameter can have a default value, which is a type. This is specified the same way we would specify a default value for a function parameter. Examples for these are shown in the following snippet:

template<typename T>
class wrapper { /* ... */ };
template<typename T = int>
class wrapper { /* ... */ };
Supplying arguments to the template instances

The name of the type template parameter can be omitted, which can be useful in forwarding declarations:

template<typename>
class wrapper;
template<typename = int>
class wrapper;
Supplying arguments to the template instances omitting the parameter name

C++11 has introduced variadic templates, which are templates with a variable number of arguments. A template parameter that accepts zero or more arguments is called a parameter pack. A type template parameter pack has the following form:

template<typename... T>
class wrapper { /* ... */ };
Defining a type template parameter pack

Variadic templates will be addressed in the “Variadic Templates” section. Therefore, we won’t get into details about these kinds of parameters at this point.

C++20 has introduced concepts and constraints. Constraints specify requirements on template arguments. A named set of constraints is called a concept. Concepts can be specified as type template parameters. However, the syntax is a little bit different. The name of the concept (followed by a list of template arguments in angle brackets if the case) is used instead of the typename or the class keyword. Examples, including concepts with a default value and constrained type template parameter pack, are shown as follows:

template<WrappableType T>
class wrapper { /* ... */ };
template<WrappableType T = int>
class wrapper { /* ... */ };
template<WrappableType... T>
class wrapper { /* ... */ };
Defining a concept of type template parameters

Concepts and constraints are discussed in the “Concepts and Constraints” section. We’ll learn more about these kinds of parameters in that section. For now, let’s look at the second kind of template parameters, non-type template parameters.

Non-type template parameters

Template ...