Function template SFINAE
1234567891011121314151617 | #include <type_traits>
#include <limits>
#include <cmath>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
equal(T lhs, T rhs)
{
return lhs == rhs;
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
equal(T lhs, T rhs)
{
return std::abs(lhs - rhs) < 0.0001;
} |
This pattern is licensed under the CC0 Public Domain Dedication.
Intent
Conditionally instantiate a function template depending on the template arguments.
Description
We provide two implementations of the equal
function template:
- The template on lines 5–10 will only be instantiated when
T
is an integral type. - The template on lines 12–17 will only be instantiated when
T
is a floating point type.
We have used std::enable_if
on line 6 and
line 13 to force instantiation to succeed only for the appropriate
template arguments. This relies on Substitution Failure Is Not An
Error
(SFINAE), which states that
failing to instantiate a template with some particular
template arguments does not result in an error and simply discards
that instantiation.
The second template argument of std::enable_if
— in this case,
bool
— is what the full std::enable_if<...>::type
evaluates to when the first template argument is true
. This means
that the return type of equal
will be bool
.
If you want to simply prevent a template from being instantiated
for certain template arguments, consider using
static_assert
instead.