关于boost::any,今天心血来潮,顺手实现了一个。不想加有关type_info的东西,所以自我创造了一个用dynamic_cast的版本,仅供学习。
要用当然要boost::any的嘛。
关于模板,首先说两条:
1. 类模板
(缺点)类模板不能自动推导模板参数(意思是当要用到某个模板类,比如A,那么你使用的时候一定要有模板参数,比如A<int>,编译器不能自动推导),只能通过特化模板而是编译器选择合适的特化版本,
(优点)类模板可以通过类模板把推导后的模板参数输出,通常使用 typedef _Type value; 。
2. 函数模板
(优点)函数模板可以自动推导模板参数(意思是你顶一个模板函数,比如f,那么使用的时候不一定要有模板参数,比如f(123),编译器会自动推导123为int),当然这里可以靠函数重载和编译器匹配顺序,来决定很多事情。
(缺点)函数模板不能输出推导后的类型。
1 struct any
2 {
3 struct content
4 {};
5
6 template<typename _U>
7 struct impl : public content
8 {
9 _U _u;
10
11 impl(const _U& u)
12 : _u(u)
13 {}
14
15 typedef _U type;
16 };
17
18 template<typename _U>
19 any(const _U& c)
20 : _t(new impl<_U>(c))
21 {}
22
23 content* _t;
24 };
那么要实现any,any本身不是类模板,所以要接受任何参数,那么其构造函数必须是函数模板,但是函数模板不能导出推导后的类型,那么需要靠类模板来保存类型信息。
1 struct any
2 {
3 template<typename _U>
4 any(const _U& c)
5 {}
6 };
可以看出,上面的any定义可以接受任何类型的参数,比如 any t1(1); any t2(1.0); 注意1和1.0不一样。 但是输入的东西没有保存起来,起不到一个任意类型变量的作用(就是个空壳)。所以继续修改,
1 struct any
2 {
3
4 template<typename _U>
5 struct impl
6 {
7 _U _u;
8
9 impl(const _U& u)
10 : _u(u)
11 {}
12
13 typedef _U type;
14 };
15
16 template<typename _U>
17 any(const _U& c)
18 : _t(new impl<_U>(c))
19 {}
20
21 impl<???>* _t;
22 };
前面说过,类模板可以保存类型信息,所以加入了一个 impl 的类模板,通过any的构造函数推导出的类型,将参数的类型保存在impl里面。看到最后一样的问号了吧,哪里要写什么呢?any其实不知道他自己里面是什么东西呀,所以为了让any知道,定义一个类A,然后让impl继承它,那么这个A就是所有impl<>的父类了,不管impl里面是什么,都是一个A。当然起名A不好听,换个吧。
1 #include <typeinfo>
2
3 using namespace std;
4
5 struct any
6 {
7 struct content
8 {
9 virtual ~content() {};
10 };
11
12 template<typename _U>
13 struct impl : public content
14 {
15 _U _u;
16
17 impl(const _U& u)
18 : _u(u)
19 {}
20
21 typedef _U type;
22 };
23
24 template<typename _U>
25 any(const _U& c)
26 : _pc(new impl<_U>(c))
27 {}
28
29 ~any()
30 {
31 delete _pc;
32 }
33
34 template<typename _T>
35 _T& get()
36 {
37 impl<_T>* p = dynamic_cast<impl<_T>*>(_pc);
38 if(0 == p)
39 throw bad_cast();
40 return p->_u;
41 }
42
43 private:
44 content* _pc;
45 };
46
47 void main()
48 {
49 any a(10);
50 any b(1.0);
51 int x = a.get<int>();
52 double y = b.get<double>();
53 }
现在可以看到, content代替了那个不知道些什么类型的???,这个技术名字叫类型消除技术,在boost里面用的很多,也算是一个经典的技术了。
posted on 2009-02-20 14:27
尹东斐 阅读(2245)
评论(8) 编辑 收藏 引用