Substitution failure is not an error: Difference between revisions

Content deleted Content added
Tags: Twinkle Reverted
No edit summary
 
(7 intermediate revisions by 5 users not shown)
Line 1:
{{Short description|C++ programming technique}}
{{useUse dmy dates|date=JanuaryDecember 20122023}}
<!-- Please do not remove or change this AfD message until the discussion has been closed. -->
'''Substitution failure is not an error''' ('''SFINAE''') refers tois a situationprinciple in [[C++]] where an invalid substitution of [[Template (C++)|template]] parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.<ref>{{cite book | last=Vandevoorde | first=David |author2=Nicolai M. Josuttis | title=C++ Templates: The Complete Guide | publisher=Addison-Wesley Professional | year=2002 | isbn=0-201-73484-2}}</ref>
{{Article for deletion/dated|page=Substitution failure is not an error|timestamp=20220717091636|year=2022|month=July|day=17|substed=yes|help=off}}
<!-- Once discussion is closed, please place on talk page: {{Old AfD multi|page=Substitution failure is not an error|date=17 July 2022|result='''keep'''}} -->
<!-- End of AfD message, feel free to edit beyond this point -->
'''Substitution failure is not an error''' ('''SFINAE''') refers to a situation in [[C++]] where an invalid substitution of [[Template (C++)|template]] parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.<ref>{{cite book | last=Vandevoorde | first=David |author2=Nicolai M. Josuttis | title=C++ Templates: The Complete Guide | publisher=Addison-Wesley Professional | year=2002 | isbn=0-201-73484-2}}</ref>
 
Specifically, when creating a candidate set for [[overload resolution]], 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 onethat the C++ standard grantspermits discarding such treatmenta substitution error as mentioned.<ref>International Organization for Standardization. "ISO/IEC 14882:2003, Programming languages &mdash; C++", § 14.8.2.</ref> If one or more candidates remain and overload resolution succeeds, the invocation is well-formed.
 
==Example==
Line 26 ⟶ 23:
f<int>(10); // Call #2. Without error (even though there is no int::foo)
// thanks to SFINAE.
return 0;
}
</syntaxhighlight>
Line 39 ⟶ 37:
 
template <typename T>
struct has_typedef_foobarHasTypedefFoobar {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
Line 57 ⟶ 55:
};
 
struct fooFoo {
typedef float foobar;
};
Line 63 ⟶ 61:
int main() {
std::cout << std::boolalpha;
std::cout << has_typedef_foobarHasTypedefFoobar<int>::value << std::endl; // Prints false
std::cout << has_typedef_foobarHasTypedefFoobar<fooFoo>::value << std::endl; // Prints true
return 0;
}
</syntaxhighlight>
Line 76 ⟶ 75:
#include <iostream>
#include <type_traits>
 
template <typename... Ts>
using void_t = void;
 
template <typename T, typename = void>
struct has_typedef_foobarHasTypedefFoobar : std::false_type {};
 
template <typename T>
struct has_typedef_foobarHasTypedefFoobar<T, std::void_t<typename T::foobar>> : std::true_type {};
 
struct fooFoo {
using foobar = float;
};
Line 92 ⟶ 88:
int main() {
std::cout << std::boolalpha;
std::cout << has_typedef_foobarHasTypedefFoobar<int>::value << std::endl;
std::cout << has_typedef_foobarHasTypedefFoobar<fooFoo>::value << std::endl;
return 0;
}
</syntaxhighlight>
Line 103 ⟶ 100:
 
template <typename T>
using has_typedef_foobar_tHasTypedefFoobarUnderlying = typename T::foobar;
 
struct fooFoo {
using foobar = float;
};
Line 111 ⟶ 108:
int main() {
std::cout << std::boolalpha;
std::cout << std::is_detected<has_typedef_foobar_tHasTypedefFoobarUnderlying, int>::value << std::endl;
std::cout << std::is_detected<has_typedef_foobar_tHasTypedefFoobarUnderlying, fooFoo>::value << std::endl;
return 0;
}
</syntaxhighlight>
 
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.
Line 123 ⟶ 121:
{{C++ programming language}}
 
{{use dmy dates|date=January 2012}}
[[Category:C++]]
[[Category:Articles with example C++ code]]