您的位置:首页 > 编程语言 > C语言/C++

由is_base_of看C++中的SFINAE

2015-09-21 15:41 537 查看
SFINAE, 全称为"匹配失败并不是一种错误(Substitution Failure Is Not An Error). 这个源码看着还是有点费劲的!先举个例子。

template<typename T, bool C = true>
struct if_ {
static const int value = 1;
};

template<typename T>
struct if_<T, true> {
static const int value = 2;
};

int main() {
printf("value: %d\n", if_<int>::value);
}
这里肯定选特化的版本,输出是2。类模板可以具有类型或值形参的默认实参。
使用等号 (=) 后跟类型名称或值来指定默认参数。因为值形参C默认是true,不显式指定的情况下就是true。相当于:

template<typename T, bool C = true>
struct if_ {};

template<typename T>
struct if_<T, false> {
static const int value = 1;
};

template<typename T>
struct if_<T, true> {
static const int value = 2;
};

int main() {
printf("value: %d\n", if_<int>::value);
}
下面,来看另一个例子!首先来一个判断类型是基本类型还是类类型的模板类。

template <typename T>
class is_class {
template <typename U>
static char helper(int U::*);
template <typename U>
static int helper(...);
public:
static const bool value = sizeof(helper<T>(0)) == 1;
};


最后是is_base_of出场:

template <typename T1, typename T2>
struct is_same {
static const bool value = false;
};

template <typename T>
struct is_same<T, T> {
static const bool value = true;
};

template<typename Base, typename Derived, bool = (is_class<Base>::value && is_class<Derived>::value)>
class is_base_of {
template <typename T>
static char helper(Derived, T);
static int helper(Base, int);
struct Conv {
operator Derived();
operator Base() const;
};
public:
static const bool value = sizeof(helper(Conv(), 0)) == 1;
};

template <typename Base, typename Derived>
class is_base_of<Base, Derived, false> {
public:
static const bool value = is_same<Base, Derived>::value;
};

template <typename Base>
class is_base_of<Base, Base, true> {
public:
static const bool value = true;
};


然后还看有人像下面这么实现,简单的让我不敢相信,没严格测试,不知道是否够健壮!原理就是:派生类可以隐式转化为基类!如果转换成功,就用非模板形式,返回true,反之,返回false!

template<typename T>
class CTestBase{
public:

static bool testbase(const T&){return true;}
template<typename U>
static bool testbase(U&){return false;}
};

template<typename T1, typename T2>
bool is_base_of(){

return CTestBase<T1>::testbase(T2());
}

template<typename T1, typename T2>
bool instanceof(const T2&){
return CTestBase<T1>::testbase(T2());
}


注意做实参的T2()后面的这个括号,这就是用默认构造函数生成的无名临时对象了,不是类型。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: