A Bite of Template in C++ (1)

From recent C++ programming, I acquired two features of C++ template, which are new to me. Namely, not only types are allowed to be template arguments, and partial or explicit specialization of template.

Beyond Typename

The keyword template is used in C++ to describe a series of functions working on different types in similar manner, while template actually has much wider usage. For example, template can be used to describe a series of classes or structs as well (“C++ Primer Plus (6th edition)” introduces this a bit later in Chapter 14, although I totally forget). What is more, not only typename (or class) can be listed as template parameter, but also variables can be added into template parameter list. Here comes an example:

Partial or Explicit Specialization

For limited specific types, sometimes we might like to treat them differently from almost all other types, then partial specialization would be really useful. We remove the determined type from the list, just like “overloading” the template with different number of parameters, and complete the parameter list with types decided, so that it can be “passed to” the original template. However, it is not a wrapper, because it has to totally rewrite the defination. Compare the following example with the example in last section.

When use the template, compiler would try to find the best match. The more specific, the better match.

Explicit specialization means all parameters are specified. C++ allows empty template parameter list, like this:

But for some historical reasons, explicit specialization of member functions is not allowed in classes.
Partial specialization is not allowed for function templates, as discussed in A Bite of Template in C++ (3).

SFINAE

SFINAE stands for “Substitution Failure Is Not An Error”. The standard states:

If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. Only invalid types and expression in the immediate context of the function type and its template parameter types can result in a deduction failure.

Under the philosophy of SFINAE, we have chance to achieve compile-time switch for templates, using above two features. Here I elaborate the approach with an example of std::enable_if from Eli Bendersky’s website:

But be awared that this approach cannot remove member functions during compile. Here comes a failed attempt:

Future Work

Next post may be about template parameter pack, variadic templates and how to conditionally compile member functions.

Credits