SFINAE: Substitution Failure Is Not An Error (替换失败不是错误)
SFINAE 可用于模板类型参数 和 返回值类型 两个地方,
在这两个地方做类型不正确的操作 它不会报错和退出程序, 而是跳过当前匹配去尝试其他匹配.
函数体内做类型不正确的操作, 会报错.
#include <iostream>
using std::cout;
using std::endl;
struct book {
// 重新定义一个类型, 这个类型叫做 page_type
// page_type 属于 book 作用域中的一个成员.
typedef int page_type;
// 使用另外一种语法来重新定义一个类型, 这个类型叫做 name_type,
// name_type 属于 book 作用域中的一个成员.
using name_type = string;
};
int main(void) {
// 使用book结构中的类型别名来定义变量.
book::page_type a = 1099;
book::name_type b = "C++ Standard Library";
// author_type 不存在于 book 结构中, 因此会报错.
book::author_type c = "Nicolai M.Josuttis"; // error.
// output:
// 'author_type': is not a member of 'book'
return 0;
}
模板尖括号里做类型不正确的操作, 不会报错.
#include <iostream>
using std::cout;
using std::endl;
struct book {
typedef int page_type;
using name_type = string;
};
// T::author_type 是一个不存在的东西, 在这里叫做替换失败, 不是类型操作错误.
// 当替换失败时, 编译器会跳过这个匹配, 继续寻找下一个模板函数.
template<typename T, class U = typename T::author_type>
void example(T t) {
cout << "template<typename T = book::author_type > void example();" << endl;
}
template<typename T>
void example(T t) {
cout << "void example(book b)" << endl;
}
int main(void) {
book b;
example(b);
return 0;
}