SFINAE 意为“匹配失败并不是错误”。
常用于编译期间,模板参数类型的判断和查找——会遍历查找所有可能匹配的参数类型,如果找不到,就编译失败。
C++11 中的 type traits 库中大量运用了 SFINAE。例如 is_class, is_pointer, is_member_function_pointer, is_const 等。
测试(1)
#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;
using std::cin ;
using std::cout ;
using std::endl ;
using std::string ;
namespace SFINAE {
// 定义判断类型
typedef char yes ;
typedef struct{ char str[2] ; } no ;
/* 判断 T 是否存在迭代器
* yes judge 函数负责判断成功的条件
* no judge 中 ... 接收除了 yes judge 以外的所有条件
* 尝试所有的 judge 匹配后, 判断得到的 judge 数据类型的大小
*/
template<typename T>
struct has_iterator {
template<typename other>
static yes judge(typename other::iterator* x) ;
template<typename other>
static no judge(...) ;
const static bool value = sizeof(judge<T>(0)) == sizeof(yes) ;
} ;
// 判断 T 是不是一个 class
template<typename T>
struct is_class {
template<typename other>
static yes judge(int other::*) ;
template<typename other>
static no judge(...) ;
const static bool value = sizeof(judge<T>(nullptr)) == sizeof(yes) ;
} ;
}
int main () {
using namespace SFINAE ;
if ( has_iterator< std::vector<int> >::value )
cout << "vector<int> 有迭代器 iterator\n" ;
if ( !has_iterator< int >::value )
cout << "int 没有迭代器\n" ;
if ( !is_class<int>::value ) cout << "int 不是 class\n" ;
if ( !is_class<char>::value ) cout << "char 不是 class\n" ;
if ( is_class<std::vector<int>>::value ) cout << "vector 是 class\n" ;
if ( is_class<is_class<int>>::value ) cout << "is_class 是 class\n" ;
return 0 ;
}