Substitution failure is not an error
来源:互联网 发布:混沌战域美人进阶数据 编辑:程序博客网 时间:2024/05/16 10:52
Substitution failure is not an error
Substitution failure is not an error (SFINAE) refers to a situation inC++ where an invalid substitution oftemplate parameters is not in itself an error. David Vandevoorde first introduced the acronym SFINAE to describe related programming techniques.[1]
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 one the C++ standard grants such treatment.[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 { typedef int foo;}; template <typename T> void f(typename T::foo) {} // Definition #1 template <typename T> void f(T) {} // Definition #2 int main() { f<Test>(10); // Call #1. f<int>(10); // Call #2. Without error (even though there is no int::foo) thanks to SFINAE.}
Here, attempting to use a non-class type in a qualified name (T::foo
) results in a deduction failure forf<int>
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 introduced to avoid creating ill-formed programs when unrelated template declarations were visible (e.g., through the inclusion of a header file), many developers 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 <iostream> template <typename T>struct has_typedef_foobar { // Types "yes" and "no" are guaranteed to have different sizes, // specifically sizeof(yes) == 1 and sizeof(no) == 2. typedef char yes[1]; typedef char no[2]; template <typename C> static yes& test(typename C::foobar*); template <typename> static no& test(...); // If the "sizeof" of the result of calling test<T>(0) would be equal to sizeof(yes), // the first overload worked and T has a nested type named foobar. static const bool value = sizeof(test<T>(0)) == sizeof(yes);}; struct foo { typedef float foobar;}; int main() { std::cout << std::boolalpha; std::cout << has_typedef_foobar<int>::value << std::endl; std::cout << has_typedef_foobar<foo>::value << std::endl;}
When T
has the nested type foobar
defined, the instantiation of the firsttest
works and 0 is successfully passed as the null pointer constant. (And the resulting type of the expression isyes
.) If it does not work, the only available function is the secondtest
, 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.)
Developers of Boost used SFINAE in boost::enable_if[3] and in other ways.
References
- Vandevoorde, David; Nicolai M. Josuttis (2002).C++ Templates: The Complete Guide. Addison-Wesley Professional. ISBN 0-201-73484-2.
- International Organization for Standardization. "ISO/IEC 14882:2003, Programming languages — C++", § 14.8.2.
- Boost Enable If
- C++
- Substitution Failure Is Not An Error
- Substitution failure is not an error
- _IsPtrType -- STL type checking on compile-time -- Substitution Failure Is Not An Error (SFINAE)
- ERROR in AppModule is not an NgModule
- VxVM:xxxx: ERROR: IPC Failure: Configuration daemon is not accessible
- Error:FAILURE: Build failed with an exception. * What went wrong: Task '' not found in root projec
- There is an error in invoking javac. A full JDK (not just JRE) is required...
- There is an error in invoking javac. A full JDK (not just JRE) is required
- There is an error in invoking javac. A full JDK (not just JRE) is required问题解决
- There is an error in invoking javac. A full JDK (not just JRE) is required问题解决
- error: 'xxx函数' is inaccessible,'Text' is not an accessible base of 'TextLine'
- PWC6345: There is an error in invoking javac. A full JDK (not just JRE) is required
- Convenience Is not an -ility
- Convenience Is Not an -ility
- $ is not defined error
- $ is not defined error
- If the job does not exist, an error from msdb.dbo.sp_delete_job is expected
- VS错误error C3872: '0x3000': this character is not allowed in an identifier
- stringstream的清空
- jquery ajax的data参数
- android多用户
- Android-ViewPagerIndicator自定义tab数量
- golang 生成随机数,时间种子改进型
- Substitution failure is not an error
- HDU 4035 Maze 树形概率DP 2011年成都网络赛E题
- iOS代码行数统计
- 那么你呢?
- jenkins+ant+svn持续集成环境搭建
- Android获取图片资源的4种方式
- WARNING: inbound connection timed out (ORA-3136)
- win8的uac原来无法关闭
- chrome安全浏览器之实现