学习Iterator笔记

  初次接触讲STL的书,翻来翻去,满眼就看到两个字“泛型”。认真学习一番之后,终于从最初的一头雾水,到现在的稍微有些领悟。

  个人感觉,应该先从第三章开始看,即:Iterator。这一章讲的内容贯穿全书。其实这章并不是只讲Iterator,而且也没把Iterator讲完,却一直在讲type——型别,认真读完之后,感觉学到了很多新东西,包括语法层面到设计模式。

  首先,Iterator本身是一种设计模式,在Design Patterns一书中P171~P181有介绍,但是那本书出现的太早了,导致上面的例子被STL源码剖析当作反例来讲。Iterator这一章的重要性在于它出现在一个矛盾点上——全书出处体现的泛型思想,本章却在翻来覆去的讲型别;全书都在泛化,本章却一直描述特化。为什么会这样呢?因为我们打开了“泛化”的窗户的同时,不可避免的进来了一些苍蝇。泛型思想讲究对所有的型别作出统一的接口,使我们能够以统一的方式去对不同的型别调用相同的算法。可是型别究竟还是不同的,为了提高运行的效率,真正实现的算法应该能够对不同的型别进行区分,选择最有利的解决办法,避免“过分的一碗水端平”导致“要么最好要么最差”的运行效率。在这种情况下,Algorithms和Containers的结合点:Iterators面临来自效率的挑战。我们都知道,Algorithm都是以Container的Iterator为传入参数的,这是泛型化设计的典型体现。因此Iterator本身是泛化的产物,此时必须承担起特化的任务,做到:

  1. 能够触发Algorithms选择最优算法的条件
  2. 不影响Containers的简洁高效

  那么,Iterator是怎么做到的呢,简单的说,就是:

  1. 从Container中获得型别,因为Iterator本身是Container的内嵌型别,这一点很容易实现;
  2. 在外部独立定义所有算法所需要的标签,如copy算法的has_trivial_default_constructor、fill算法的is_POD等等;
  3. 在每一个class中,根据自己的实际情况,将这些标签选择性的声明为内嵌型别;
  4. 建立型别萃取机,同时设定默认的标签;
  5. 对部分POD或者prime type进行特化,设定最优标签;
  6. 在算法实现时,由总函数调用型别萃取机,通过“重载”机制,激活最优算法,从而完成最优算法的选择过程。

  该过程中没有标志变量,以“型别”为“参数”,巧妙的利用重载机制,将弱类型语言转换成了一个能够逆向识别类型的语言。

 1 #include <iostream>
 2 using namespace std;
 3 struct is_int_tag{};
 4 struct not_int_tag{};
 5 struct is_int_ptr_tag{};
 6 
 7 template <class T>
 8 struct type_traits
 9 {
10     typedef not_int_tag  type_tag;
11 };
12 
13 template<>
14 struct type_traits<int>
15 {
16     typedef is_int_tag type_tag;
17 };
18 template<>
19 struct type_traits<int*>
20 {
21     typedef is_int_ptr_tag type_tag;
22 };
23 
24 template <class T>
25 void func_aux(T t, is_int_tag)
26 {
27     cout<<"this is an int : " << t <<endl;
28 }
29 template <class T>
30 void func_aux(T t, not_int_tag)
31 {
32     cout<<"this is not an int !"<< endl;
33 }
34 template <class T>
35 void func_aux(T t, is_int_ptr_tag)
36 {
37     cout<<"this is an int_ptr : "<< *t <<endl;
38 }
39 template <class T>
40 void func(T t)
41 {
42     typedef typename type_traits<T>::type_tag type_tag;
43     func_aux(t, type_tag());
44 }
45 
46 template <class U, class T>
47 void deducation_aux(U u, T t)
48 {
49     T new_variable = *u;
50     cout<<"type was deducated ! "<< new_variable <<endl;
51 }
52 template <class T>
53 void deducation(T t)
54 {
55     deducation_aux(t, *t);
56 }
57 
58 int main()
59 {
60     //type_traints
61     int i = 3;
62     func(i);
63     char c = 'c';
64     func(c);
65     int* p;
66     *p = 4;
67     func(p);
68     //argument deducation of function template
69     deducation(p);
70     return 0;
71 }
原文地址:https://www.cnblogs.com/zanzan101/p/3326275.html