Substitution failure is not an error: Difference between revisions

Content deleted Content added
No edit summary
m Task 70: Update syntaxhighlight tags - remove use of deprecated <source> tags
Line 6:
The following example illustrates a basic instance of SFINAE:
 
<sourcesyntaxhighlight lang="cpp">
struct Test {
typedef int foo;
Line 22:
// thanks to SFINAE.
}
</syntaxhighlight>
</source>
 
Here, attempting to use a non-class type in a qualified name (<code>T::foo</code>) results in a deduction failure for <code>f<int></code> because <code>int</code> has no nested type named <code>foo</code>, but the program is well-formed because a valid function remains in the set of candidate functions.
Line 30:
For example, SFINAE can be used to determine if a type contains a certain typedef:
 
<sourcesyntaxhighlight lang="cpp">
#include <iostream>
 
Line 61:
std::cout << has_typedef_foobar<foo>::value << std::endl; // Prints true
}
</syntaxhighlight>
</source>
 
When <code>T</code> has the nested type <code>foobar</code> defined, the instantiation of the first <code>test</code> works and the null pointer constant is successfully passed. (And the resulting type of the expression is <code>yes</code>.) If it does not work, the only available function is the second <code>test</code>, and the resulting type of the expression is <code>no</code>. 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.
Line 68:
In [[C++11]], the above code could be simplified to:
 
<sourcesyntaxhighlight lang="cpp">
#include <iostream>
#include <type_traits>
Line 90:
std::cout << has_typedef_foobar<foo>::value << std::endl;
}
</syntaxhighlight>
</source>
 
With the standardisation of the detection idiom in the [http://en.cppreference.com/w/cpp/experimental/lib_extensions_2 Library fundamental v2 (n4562)] proposal, the above code could be re-written as follows:
<sourcesyntaxhighlight lang="cpp">
#include <iostream>
#include <type_traits>
Line 109:
std::cout << std::is_detected<has_typedef_foobar_t, foo>::value << std::endl;
}
</sourcesyntaxhighlight>
 
The developers of [[Boost C++ Libraries|Boost]] used SFINAE in boost::enable_if<ref name="enable_if">[http://www.boost.org/doc/libs/release/libs/utility/enable_if.html Boost Enable If]</ref> and in other ways.