由is_base_of看C++中的SFINAE
2015-09-21 15:41
537 查看
SFINAE, 全称为"匹配失败并不是一种错误(Substitution Failure Is Not An Error). 这个源码看着还是有点费劲的!先举个例子。
使用等号 (=) 后跟类型名称或值来指定默认参数。因为值形参C默认是true,不显式指定的情况下就是true。相当于:
最后是is_base_of出场:
然后还看有人像下面这么实现,简单的让我不敢相信,没严格测试,不知道是否够健壮!原理就是:派生类可以隐式转化为基类!如果转换成功,就用非模板形式,返回true,反之,返回false!
注意做实参的T2()后面的这个括号,这就是用默认构造函数生成的无名临时对象了,不是类型。
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()后面的这个括号,这就是用默认构造函数生成的无名临时对象了,不是类型。
相关文章推荐
- 解读C++编程中派生类的构成和创建
- 关联,聚合,组合的区别及C++实现
- 深入讲解C++数据类型转换的相关函数的知识
- C++四种类型转换的关键字及其特点
- C++ new/delete 与 new[]/delete[] 详情
- C++深拷贝,浅拷贝
- 详解C++编程中的重载流插入运算符和流提取运算符
- C++编程思想重点笔记
- C++双缓冲技术
- C++ Primer Plus第6版重点笔记
- Effective C++——条款48(第7章)
- C++ bitset类的使用与简介
- ubuntu x64下编译出现找不到 cdefs.h / c++config.h 的问题
- c++学习笔记
- c++栈管理库TCMalloc、jeMalloc
- C语言中的数组1
- C语言代码组织基础
- C语言----二维数组的存储
- 【C/C++学院】0814-引用高级、引用高级增加/auto自动变量自动根据类型创建数据/Bool/Enum/newdelete全局/大数据乘法与结构体/函数模板与auto/宽字符本地化/inline
- C语言打印100—200之间的素数