• 学习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 }
  • 相关阅读:
    iOS API 概述
    iOS开发的一些奇巧淫技3
    iOS开发的一些奇巧淫技1&2
    iOS-一键拨号
    iOS层次架构
    简单block 和 代理
    iOS开发-单例GCD
    简单的归档、接档
    通知中心与本地通知
    安装linux centos 7.7 遇到 DRM:Pointer to TMDS table invalid
  • 原文地址:https://www.cnblogs.com/zanzan101/p/3326275.html
Copyright © 2020-2023  润新知