• 《Effective C++》知识点(7)--模板与范型编程


    41. 了解隐式接口和编译期多态

         41.1 面向对象编程的世界总是以显式接口和运行期多态(polymorphism)解决问题。   

         41.2 类和模板都支持接口和多态。

    接口多态
    类class显式的,基于函数签名通过虚函数发生于运行期
    模板template隐式的,基于有效表达式通过template具体实现和函数重载解析发生于编译期
    42. 了解typename的双重意义

         42.1 声明template参数时,<class T>和<typename T>的意义完全相同。 

         42.2 模板函数里的几种变量名称

    变量名称英文定义
    从属名称 dependent names依赖于某个template参数
    嵌套从属名称nested dependent names从属名称在class内呈嵌套状
    嵌套从属类型名称nested dependent type names嵌套从属名称并指向某种类型
    非从属名称non-dependent names不依赖于任何template参数

                 缺省情况下解析器认为嵌套从属名称不是个类型,除非你告诉它是(在前面放typename)

        42.3 "typename必须作为嵌套从属类型名称的前缀词"这一规则的例外是,typename不可以出现

                在base classes list内的嵌套从属类型名称之前,也不可在member initialization list中作为

                base class修饰符。 

        42.4 使用typedef定义嵌套从属类型名称(如果名字很长)的别名。

        42.5 typename在不同编译器上表现不同,可移植性差。 

    43. 学习处理模板化基类内的名称

        43.1 "template<>"表示模板全特化,这既不是template也不是标准class,而是个特化版的具体

                某个类的template。一旦类型参数被定义,再没有其它template参数可供变化。

        43.2 基类模板可能被特化,而特化版本可能不提供和一般性模板相同的接口。所以编译器拒绝

                在模板化基类内寻找继承而来的名称(函数)。 

        43.3 继承类模板内调用模板化基类函数的三个方法

            a. 在基类函数调用动作之前加上"this->"。

            b. 使用using声明式,在继承类了声明基类函数。

            c. 明白地指出被调用的函数位于基类内(不适合虚函数)。

    44. 将与参数无关的代码抽离templates

         44.1 Templates生成多个类和多个函数,所以任何template代码都不该与某个造成膨胀的

                 template参数产生相依关系。注意template代码中,重复是隐晦的。

         44.2 因非类型模板参数而造成的代码膨胀,往往可消除,做法是以函数参数或类成员变量替换

                 template参数。

         44.3 因类型参数而造成的代码膨胀,往往可降低,做法是让带有完全相同二进制表述(比如指针

                 类型)的具现类型共享实现码。

    45. 运用成员函数模板接受所有兼容类型

         45.1 请使用成员函数模板生成"可接受所有兼容类型"的函数。

         45.2 如果声明member templates用于"泛化copy构造"或"泛化assignment操作",你还是需要声

                 明正常的copy构造函数和copy assignment操作符。

    46. 需要类型转换时请为模板定义非成员函数

         46.1 在template实参推导过程中从不将隐式类型转换函数纳入考虑。

         46.2 template class内的friend声明式可以指涉某个特定函数。使用friend是目的是支持"所有参

                 数的隐式类型转换"。

         46.3 为了让类型转换可能发生于所有实参身上,我们需要一个非成员函数;为了令这个函数被

                 自动具现化,我们需要将它声明在class内部;而在class内部声明非成员函数的唯一办法

                 就是令它为friend。这里使用friend与它的传统用途"访问class内非public成分"没有关系。  

    47. 请使用traits classes表现类型信息

         47.1 STL的5种迭代器分类

    类型描述代表
    Input只能向前,一次一步,只读且一次istream_iterators
    Output只能向前,一次一步,只写且一次ostream_iterators
    forward可读写一次以上(单向链表),继承自inputslist、tr1::hashed?
    bidirectional可向前或向后移动,继承自forwardlist、set、map
    random access可在常量时间内向前或向后跳跃任意距离,继承自bidirectionalvector、deque、string

        47.2 Traits

                Traits并不是C++关键字或一个预先定义好的组件;它们是一种技术,也是一个C++程序员

                共同遵守的协议。它对内置类型和用户自定义类型的表现必须一样好。习惯上,traits总是

                 被实现为structs,但它们往往被称为traits classes。Traits classes使得"类型相关信息"在编

                 译期可用,以模板和模板特化完成实现。整合重载技术后,traits classes有可能在编译期

                 对类型执行if...else测试。

        47.3 设计并实现一个traits class

              a. 确认若干你希望将来可取得的类型相关信息。

              b. 为该信息选择一个名称。

              c. 提供一个template和一组特化版本,内含你希望支持的类型相关信息。

        47.4 如何使用一个traits class

              a. 建立一组重载函数(劳工函数)或函数模板,彼此间的差异只在各自的traits参数。令每个函

                  数实现码与其接受之traits信息相对应。

              b. 建立一个控制函数(工头)或函数模板,它调用上述那些"劳工函数"并传递traits class所提供

                  的信息。

    48. 认识template元编程

           TMP(模板元编程),是编写基于模板的C++程序并执行于编译期的过程。

        48.1 TMP可将工作由运行期移到编译期,因而得以实现早期错误侦测和更高的执行效率(较小的

                可执行文件、较短的运行期、较少的内存需求),缺点是编译时间变长了。

        48.2 TMP可被用来生成"基于政策选择组合"的客户定制代码(如Strategy、Observer、Visitor),

                 也可用来避免生成对某些特殊类型并不适合的代码。TMP里的循环是用递归完成的。

  • 相关阅读:
    反恐验厂所需材料清单
    vsto word属性信息 并读取
    并发编程day06
    【ArcGIS微课1000例】0049:制图表达(4)---自由式制图表达
    JavaScript作用域链与预解析
    paramiko 使用总结(SSH 操作远端机器)
    Python中的shape[0]、shape[1]和shape[-1]分别是什么意思(附代码)
    Xilinx Kintex7中端FPGA解码MIPI视频,基于MIPI CSI-2 RX Subsystem架构实现,提供工程源码和技术支持
    施努卡:什么是视觉定位系统 视觉定位系统的工作原理
    Redis.conf配置文件说明
  • 原文地址:https://blog.csdn.net/myepicure/article/details/134221018