The enable_if framework fall into the generic programming category, and is resolved at compile time. It basically allow the enabling or disabling of templated members depending on a template type’s traits. The framework rely on the C++ compiler SFINAE (substitution-failure-is-not-an-error) principle, which dictate that: if an invalid argument or return type is formed during the instantiation of a function template, the instantiation is removed from the overload resolution set instead of causing a compilation error.



Because of its reliance on the SFINAE, which is not supported by all compilers, boost provide a #define to handle these special cases:

#ifndef BOOST_NO_SFINAE

The headers required for this framework are the one for enable_if itself, and the one defining type traits conditions:

#include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp>

For instance, let’s say we have a template method we want available only for arithmetic types. We could do like this:

template <class T> typename enable_if<boost::is_arithmetic<T>, T>::type foo(T t) { return t; }

If, on the other hand we want to make the method unavailable for arithmetic types, we’ll use the disable_if instead of enable_if. It’s that simple.

I am not going to go in details about type traits, as they are a whole framework in themselves and I will tackle them later in a future post.

There’s eight different variations of the enable_if.

First they have an optional lazy_ prefix, for situations in which it is necessary to avoid instantiating part of a function signature unless an enabling condition is true.

Then you have the option between enable_if or disable_if.

Finally, you can use the suffix _c needed if the conditional argument is a boolean, otherwise the condition is assumed as a type defining a static boolean member named “value“.

Here’s an example using a pure boolean condition with the _c suffix:

template <int N, class T> typename disable_if_c<N==13, T>::type foo(T t) { return t; }