#include<iostream>
/*
SFINAE
*在模板中有一个思想叫做“替换失败并非错误”
*当我们定义模板时无论是无论是偏特化,还是成员特化,还是实例化,还是...
*我们在进行调用的时候我们会对模板进行一个实参推导的过程,这时候
*只要我们找到一个匹配的模板进行正确的匹配,则不匹配的模板在匹配的过程中就被忽略掉
*这个就叫做“替换失败并非错误”
*我们可以用它侦测预定义转换,也能侦测用户定义的转换
*2016年7月4日00:17:41
*/
//1
typedef char True;
typedef struct { char a[2]; } Flase;
template<class C>
True hasIterator(typename C::iterator const *);
template<class T>
Flase hasIterator(...);
#define has_iterator(C)\
(sizeof(hasIterator<C>(0))==sizeof(True));
/*
1
*sizeof表达式出现的函数调用并不会真正的执行,它只会对
*“可能被调用的函数”返回类型感兴趣因而可以检查函数的
*返回值大小,以便确定是否是以便确定匹配的是哪个函数
2
*当我们检查"C"是否是一个含有成员iterator的指针时
*我们传入C当C中含有iterator指针时0将被转换为iter\
*ator*类型,匹配第一个模板,否则将匹配第二个可以
*接受任意参数的版本。
*/
//2
template<typename T1,typename T2>
struct CanConvert{
static True canConvert(T2);
static Flase canConvert(...);
static T1 markT1();
enum a{r=sizeof(canConvert(markT1()))==sizeof(ture) };
};
/*
*第二个与第一个含义差不多,当我们匹配传入参数T1,T2时
*markT1将会返回T1作为参数传入canConvert,当T1可以转换
*为T2时,则匹配第一个模板否则匹配第二个模板.
*/
int main() {
std::cout<<has_iterator(int);
system("pause");
return 0;
}
其实这个东西我们早已受益,想想declval。