cpp/language/sfinae

"Substitution Failure Is Not An Error"

This rule applies during overload resolution of function templates: When the explicitly specified or  for the template parameter fails, the specialization is discarded from the  instead of causing a compile error.

This feature is used in template metaprogramming.

Explanation
Function template parameters are substituted (replaced by template arguments) twice:


 * explicitly specified template arguments are substituted before template argument deduction
 * deduced arguments and the arguments obtained from the defaults are substituted after template argument deduction

Substitution occurs in
 * all types used in the function type (which includes return type and the types of all parameters)
 * all types used in the template parameter declarations

A substitution failure is any situation when the type or expression above would be ill-formed (with a required diagnostic), if written using the substituted arguments.

Only the failures in the types and expressions in the immediate context of the function type or its template parameter types are SFINAE errors. If the evaluation of a substituted type/expression causes a side-effect such as instantiation of some template specialization, generation of an implicitly-defined member function, etc, errors in those side-effects are treated as hard errors.

Substitution proceeds in lexical order and stops when a failure is encountered.

Type SFINAE
The following type errors are SFINAE errors:


 * attempting to create an array of void, array of reference, array of function, array of negative size, array of non-integral size, or array of size zero:


 * attempting to use a type on the left of a scope resolution operator and it is not a class or enumeration:


 * attempting to use a member of a type, where
 * the type does not contain the specified member
 * the specified member is not a type where a type is required
 * the specified member is not a template where a template is required
 * the specified member is not a non-type where a non-type is required


 * attempting to create a pointer to reference
 * attempting to create a reference to void
 * attempting to create pointer to member of T, where T is not a class type:


 * attempting to give an invalid type to a non-type template parameter:


 * attempting to perform an invalid conversion in
 * in a template argument expression
 * in an expression used in function declaration:


 * attempting to create a function type with a parameter of type void
 * attempting to create a function type which returns an array type or a function type

SFINAE in partial specializations
Deduction and substitution also occur while determining whether a specialization of a class template is generated by some  or the primary template. Compilers do not treat a substitution failure as a hard-error during such determination, but ignore the corresponding partial specialization declaration instead, as if in the overload resolution involving function templates.

Notes: currently partial specialization SFINAE is not formally supported by the standard (see also ), however, LFTS requires it works since version 2 (see also detection idiom).

Alternatives
Where applicable, tag dispatch are usually preferred over use of SFINAE.