Substitution failure is not an error (SFINAE) is a principle in
C++ where an invalid substitution of
template
Template may refer to:
Tools
* Die (manufacturing), used to cut or shape material
* Mold, in a molding process
* Stencil, a pattern or overlay used in graphic arts (drawing, painting, etc.) and sewing to replicate letters, shapes or designs
Co ...
parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.
Specifically, when creating a candidate set for
overload resolution
In some programming languages, function overloading or method overloading is the ability to create multiple functions of the same name with different implementations. Calls to an overloaded function will run a specific implementation of that f ...
, some (or all) candidates of that set may be the result of instantiated templates with (potentially deduced) template arguments substituted for the corresponding template parameters. If an error occurs during the substitution of a set of arguments for any given template, the compiler removes the potential overload from the candidate set instead of stopping with a compilation error, provided the substitution error is one the C++ standard grants such treatment.
[International Organization for Standardization. "ISO/IEC 14882:2003, Programming languages — C++", ยง 14.8.2.] If one or more candidates remain and overload resolution succeeds, the invocation is well-formed.
Example
The following example illustrates a basic instance of SFINAE:
struct Test ;
template
void f(typename T::foo) // Definition #1
template
void f(T) // Definition #2
int main()
Here, attempting to use a non-class type in a qualified name (
T::foo
) results in a deduction failure for
f
because
int
has no nested type named
foo
, but the program is well-formed because a valid function remains in the set of candidate functions.
Although SFINAE was initially introduced to avoid creating ill-formed programs when unrelated template declarations were visible (e.g., through the inclusion of a header file), many developers later found the behavior useful for compile-time introspection. Specifically, it allows a template to determine certain properties of its template arguments at instantiation time.
For example, SFINAE can be used to determine if a type contains a certain typedef:
#include
template
struct has_typedef_foobar ;
struct foo ;
int main()
When
T
has the nested type
foobar
defined, the instantiation of the first
test
works and the null pointer constant is successfully passed. (And the resulting type of the expression is
yes
.) If it does not work, the only available function is the second
test
, and the resulting type of the expression is
no
. An ellipsis is used not only because it will accept any argument, but also because its conversion rank is lowest, so a call to the first function will be preferred if it is possible; this removes ambiguity.
C++11 simplification
In
C++11
C++11 is a version of the ISO/ IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versio ...
, the above code could be simplified to:
#include
#include
template
using void_t = void;
template
struct has_typedef_foobar : std::false_type ;
template
struct has_typedef_foobar> : std::true_type ;
struct foo ;
int main()
With the standardisation of the detection idiom in th
Library fundamental v2 (n4562)proposal, the above code could be re-written as follows:
#include
#include
template
using has_typedef_foobar_t = typename T::foobar;
struct foo ;
int main()
The developers of
Boost
Boost, boosted or boosting may refer to:
Science, technology and mathematics
* Boost, positive manifold pressure in turbocharged engines
* Boost (C++ libraries), a set of free peer-reviewed portable C++ libraries
* Boost (material), a material b ...
used SFINAE in boost::enable_if
[Boost Enable If](_blank)
/ref> and in other ways.
References
{{use dmy dates, date=January 2012
C++
Articles with example C++ code
Software design patterns