//xtr1common文件
// TEMPLATE CLASS enable_if
template<bool _Test, class _Ty = void>//第一个模板参数类型bool,这是一种技术
struct enable_if
{ // type is undefined for assumed !_Test
};
template<class _Ty>
struct enable_if<true, _Ty>//这里用到了偏特化,模板实例化时只有第一个模板那参数是true的才会使用此偏特化版本,此时才有typedef _Ty type
{ // type is _Ty for _Test
typedef _Ty type;
};
利用模板偏特化技术,第一个模板参数为true的时候,会用第二个类,否则用第一个类。
typename std::enable_if<true, int>::type t; //正确
typename std::enable_if<true>::type; //可以通过编译,没有实际用处,推导的模板是偏特化版本,第一模板参数是true,第二模板参数是通常版本中定义的默认类型即void
typename std::enable_if<false>::type; //无法通过编译,type类型没有定义
typename std::enable_if<false, int>::type t2; //同上
template <typename T>//std::is_trivial<T>::value为true会使用这个函数
typename std::enable_if<std::is_trivial<T>::value>::type SFINAE_test(T value)
{
std::cout<<"T is trival"<<std::endl;
}
template <typename T>//std::is_trivial<T>::value为false会使用这个函数
typename std::enable_if<!std::is_trivial<T>::value>::type SFINAE_test(T value)
{
std::cout<<"T is none trival"<<std::endl;
}
SFINAE_test(std::string("123"));//对应第一个函数
SFINAE_test(123);//对应第二个函数
下面这个例子,只有T为int才会编译正确,否则std::is_integral<T>::value, bool>为false,enable_if 就不会有typedef type,就会编译错误
template <typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
is_odd(T t) {
return bool(t%2);
}
template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even(T t) {
return !is_odd(t);
}