A Bite of Template in C++ (1)
10 Jun 2018 Languages C/C++ metaprogramming SFINAEFrom 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
- Stephen Prata - Thanks to your book “C++ Primer Plus”, where I learnt C++.
- cppreference.com - A great website for reference of C++.
- SFINAE and enable_if - Thanks Eli Bendersky for your great post.
- Why is explicit specialization of member function not allowed in class? - Thanks Sergey Zubkov for your explaination why explicit specialization is not allowed in class.