一、类型萃取
笔者目前以这种使用场景来解释什么是类型萃取,为什么需要类型萃取?看代码会更加明了。
Demo.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #ifndef DEMO_H #define DEMO_H
template<class _Ty> class Object { private: _Ty value; public: Object(_Ty val = 0) : value(val) {} ~Object() {}
const _Ty Value()const { return value; } _Ty Value() { return value; } };
template<class _Container> class Container { private: _Container c; public: Container(_Container x = 0) : c(x) {}
返回值类型 ? ? getObjectValue() { return c.Value(); } }; #endif
|
通过这个场景可以看出,我们非常有必要知道c.Value()的返回值类型,若是在Object类中,我们很容易知道返回值类型就是_Ty,但是经过一次封装后,通过封装的Container类是不能直接去获得存储在其中的对象的成员中的类型。那么类型萃取就诞生了。(不仅仅局限于这个原因,更重要C++追求效率的缘故,这个后面再说)
那我们加上类型萃取器(类)后:
Demo.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #ifndef DEMO_H #define DEMO_H
template<class _Ty> class Object { private: _Ty value; public: typedef _Ty value_type;
Object(_Ty val = 0) : value(val) {} ~Object() {}
const _Ty Value()const { return value; } _Ty Value() { return value; } };
template<class _Object> struct Object_traits { typedef typename _Object::value_type value_type; };
template<class _Container> class Container { private: _Container c; public: Container(_Container x = 0) : c(x) {} typename Object_traits<_Container>::value_type getObjectValue() { return c.Value(); } }; #endif
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <iostream> #include "Demo.h" using namespace std; int main() { Object<int> iobj(10); Container<Object<int>> icon(iobj); cout << icon.getObjectValue() << endl;
Object<double> dobj(3.14); Container<Object<double>> dcon(dobj); cout << dcon.getObjectValue() << endl;
return 0; }
|
运行结果:
![在这里插入图片描述](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
类型萃取时机总结:
- 模板类A作为模板类B的模板参数,并且模板B类中需要使用模板类A中的模板参数类型
二、通过类型萃取实现函数重载
通过这几种组合起来,我们能达到早绑定的效果:在编译时期就确定函数的调用时机。
Demo.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #ifndef DEMO_H #define DEMO_H #include <iostream> using namespace std;
template<class _Ty> class Object { private: _Ty value; public: typedef _Ty value_type;
Object(_Ty val = 0) : value(val) {} ~Object() {}
const _Ty Value()const { return value; } _Ty Value() { return value; } };
template<class _Object> struct Object_traits { typedef typename _Object::value_type value_type; };
template<class _OBj> typename Object_traits<_OBj>::value_type dif_Condition(const _OBj&) { return typename Object_traits<_OBj>::value_type(); }
template<class _Container> class Container { private: _Container c; public: Container(_Container x = 0) : c(x) {} typename Object_traits<_Container>::value_type getObjectValue() { return c.Value(); } private: void __fun(int) { cout << " int "<< endl; } void __fun(double) { cout << " double " << endl; } public: void fun() { __fun(dif_Condition(c)); } }; #endif
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <iostream> #include "Demo.h" using namespace std; int main() { Object<int> iobj(10); Container<Object<int>> icon(iobj); cout << icon.getObjectValue() << endl; icon.fun();
Object<double> dobj(3.14); Container<Object<double>> dcon(dobj); cout << dcon.getObjectValue() << endl; dcon.fun(); return 0; }
|
测试结果:
![在这里插入图片描述](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
本节主要为了充分理解类型粗萃取的原理,后面将会对STL中的迭代器进行论述。