zoukankan      html  css  js  c++  java
  • 关于模板的基本知识

    C++标准库的开发,几乎所有东西都被设计为模板形式,所以掌握Template技术是学习标准库的基础。

    回顾下Template,它是一种针对“一个或多个尚未明确类型”所编写的函数或类别,其中共性是逻辑相同,异处在于该逻辑中使用到的类型需要用户自己设定。

    当然,我们在使用Template时,可以“显式explicitly”或“隐式implicitly”地将类型当做参数来传递

    最简单的:

    template <class T>    // 因为class尚未确定,暂时用T代替
    inline const T& max (const T& a, const T& b)
    {
           return a < b? b : a;      
    }

    Template并非一次编译就能够产生出所有可用类型的代码,而是需要用户进行设定,设定完之后编译器才能根据用户设定的值进行产生合适的类型,来产生调用操作。

    关于Template函数可移植性的操作方式就是在头文件中以inline function来实现。

    接下来需要对template的几个重要特性进行说明:

    -----------------------------------------------------定义函数模板-----------------------------------------------------

    1. 模板形参表:

    定义的这些形参就像函数形参表,该形参表定义了特定类型的局部变量,但并不初始化,直到运行时再提供实参来初始化形参。

    模板形参可以是:表示类型的类型形参(type)、表示常量表达式的非类型形参(non-type)

    类型形参的关键字是class或typename,其实两个关键字没什么大区别。

    2. 使用函数模板:

    使用函数模板时,编译器会推断哪个模板实参绑定到模板形参,一旦编译器确定了实际的模板实参,那么这个编译器就实例化了函数模板的一个实例。

    所以,是由编译器来承担为我们使用的每种类型而编写函数的单调工作。

    3. inline函数模板:

    函数模板加上inline的方式和一般函数类似,但写的时候注意,是放在模板形参之后,函数返回类型之前:

    template <typename T>

    inline T play(const T& t1, const T& t2);

    -----------------------------------------------------定义类模板-----------------------------------------------------

    1. 使用类模板:

    必须为模板形参显式的指定实参:

    Queue<int> qi;

    Queue<vector<double>> qc;

    Queue<string> qs;

    实例化工作还是由编译器来完成。

    模板形参:

    就好像一般的函数形参,形参名字为任意设计,名字前需要添加“类型”。

    区别在于,形参可以是类型形参(一个未知类型),也可以是非类型形参(一个未知值)。

    模板类型形参:

    由关键字class或typename构成,这两个关键字作用基本相同,只是typename比class更直观。

    对于模板内部定义类型成员,但编译器无法知道这个成员是一个值还是类型:

    template <typename T>
    void Function(T* t)
    {
        T::size_type *p;    // 这个size_type是自定义的,所以编译器默认是收成员,而不是类型成员
        
        // 除非
        typename T::size_type *pi;
    }

    所以,typename还是给类型成员指定是类型还是数据。

    非类型模板形参:

    假如模板的类型不是一个类型,而是一个数据,该形参是用来作为模板内部的常量值。

    那么我们如何来编写一个泛型程序呢?这取决于某段代码是否是类型不确定的。比如一个比较操作:

    if (v1 < v2) return -1;

    if (v1 > v2) return 1;

    return 0;

    那么v1与v2有很多种可能,常量或类型?? 如果是常量则比较简单,但如果是类型,是否重载了<与>运算符的操作呢?

     模板实例化:

     模板如果看成是图纸,那么实例化就是按照图纸制作出实际产品,这需要用户提供模板实参,由编译器来完成实例化过程。

    1. 实例化类时,编译器首先会自动创建用户指定名字的类。实例化时,指定模板实参是必须的。

    2. 但实例化函数模板时,根据用户填入的实参,编译器可能会进行自动判断实参类型。

    成员模板:

    一个类的成员函数也可以是模板函数,但不可以是虚函数,也不能有缺省参数:

    class MyClass
    {
        // ....
        template <class T>
        void fun(const T &t);
    }
  • 相关阅读:
    vlan原理与配置
    路由协议-ospf
    路由协议-rip
    人品
    阿波罗礼赞
    跳石头
    FBI树
    方程求解
    循环比赛
    国王的游戏
  • 原文地址:https://www.cnblogs.com/davidsguo008/p/3672760.html
Copyright © 2011-2022 走看看