Substitution failure is not an error: Difference between revisions

Content deleted Content added
mNo edit summary
Line 8:
<source lang="cpp">
struct Test {
typedef int typefoo;
};
 
template <typename T>
void f(typename T::typefoo) {} // Definition #1
 
template <typename T>
Line 19:
int main() {
f<Test>(10); // Call #1.
f<int>(10); // Call #2. Without error (even though there is no int::foo) thanks to SFINAE.
}
</source>
Line 33:
 
template <typename T>
struct has_typedef_typehas_typedef_foobar {
// Variables "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
Line 40:
 
template <typename C>
static yes& test(typename C::typefoobar*);
 
template <typename>
Line 51:
 
struct foo {
typedef float typefoobar;
};
 
int main() {
std::cout << std::boolalpha;
std::cout << has_typedef_typehas_typedef_foobar<int>::value << std::endl;
std::cout << has_typedef_typehas_typedef_foobar<foo>::value << std::endl;
}
</source>
 
When <code>T</code> has the nested type <code>typefoobar</code> defined, the instantiation of the first <code>test</code> works and 0 is successfully passed as the null pointer constant. (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.)
 
Developers of [[Boost C++ Libraries|Boost]] used SFINAE to great effect 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.