C++ -学习笔记(15)SFINAE 匹配失败并不是错误

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 ;
}

猜你喜欢

转载自blog.csdn.net/nishisiyuetian/article/details/81627608