由is_base_of看C++中的SFINAE

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()后面的这个括号,这就是用默认构造函数生成的无名临时对象了,不是类型。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值