Today is the day! We host the C/C++ Madrid meetup
It’s finally here and full of interesting content. The C and C++ community gathers together to talk about metaprogramming.
Final templates tips: Duck typing and SFINAE
C++ templates are processed in two phases: Declaration and instantiation. First the compiler checks the declaration of the template for syntactical correcness, but what happens to things that depends on template parameters?
The compiler doesn’t know anything about that parameters until template instantiation, so it delays the analysis of such things until the second phase, which is executed after a template is instanced.
Consider this function template:
void f( const T& t)
T could be any type, so the question is: Has this type a member function
The answer is: Nobody knows, and the compiler doesn’t care. Until template instantiation.
So if you use that template correctly, using a type
T with a member function
f(), the code compiles and works. But, if the type is not correct? Is that a compilation error? Enter SFINAE.
SFINAE, Specialization Failure Is Not An Error, is the colloquial name of a rule on the C++ Language Standard saying that a failure when trying to instantiate a template is not a compilation error, but the compiler continues trying with other alternatives (More templates or overloads).
Following with the duck typing example, if we use the function template with a type with no member function
f(), that doesn’t result in a compilation error (And then the compiler aborting compilation), but the compiler continues searching for other template or overload that matches the call.
That behavior could be used to “enable” a template only if the template parameters passed fulfill a certain property or requirement. For example:
template<typename T , typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
void compare( T lhs , T rhs );
That template could be used with floating-point parameters only. Note the
std::enable_if template there. That template provided by the standard library allows us to use SFINAE in an easy way. What it does is to declare a member type
::type if a certain boolean condition is true.
If we reference that member (
typename std::enable_if::type and the condition is false, than the template has no type member, and the template is ill-formed. But do you remember the SFINAE rule? Instead of aborting compilation because the ill-formed template, the compiler continues.
So the result is that we “disabled” that template because the parameter was not a floating-point type. Cool, isn’t?
It’s never too late to sing up for the C/C++ Madrid meetup!!
We will try to broadcast the event through hangouts, check below: