Substitution Failure Is Not An Error (SFINAE) is a Template Metaprogramming rule in C++: when the compiler substitutes template arguments and the result is ill-formed, that specialization is silently discarded from the overload set rather than producing a compile error.
Warning
SFINAE has largely been superceded by if constexpr and Concepts. Use with caution!
Example
// Only enabled when T is an integral type
template <typename T>
auto to_string(T value) -> std::enable_if_t<std::is_integral_v<T>, std::string> {
return std::to_string(value);
}
// Only enabled when T has a .str() method
template <typename T>
auto to_string(T value) -> decltype(value.str()) {
return value.str();
}If T = double, the first overload’s enable_if_t produces an invalid type and is discarded. If T = int, the second overload’s decltype(value.str()) is ill-formed and is discarded. No error, the compiler just picks whichever overload survives.
enable_if
The standard mechanism for SFINAE:
template <bool Condition, typename T = void>
struct enable_if {}; // no 'type' member when false
template <typename T>
struct enable_if<true, T> {
using type = T; // 'type' exists only when true
};