zoukankan      html  css  js  c++  java
  • C++中的模板

    Templates

    定义一个模板使用的关键字:classtypename

    在定义作为模板的时候:classtypename,作用是一样的


    出处:http://www.cplusplus.com/doc/tutorial/templates/

    函数模板

    1 定义方式

    template <class identifier> function_declaration;
    template <typename identifier> function_declaration;


    2 Example

    template <class T>
    T GetMax (T a, T b)
    {
    T result;

    result = (a>b)? a : b;

    return (result);
    }


    3 使用方法

    function_name <type> (parameters);

    例如:
    int x,y;
    GetMax <int> (x,y);


    对于内部类型,通常是可以无需制定具体的类型,编译器会自动识别,

    而是写成:

     

    int x,y;

    GetMax(x,y); //x,y为相同的类型


     

    int x;

    long y;

    GetMax(x,y); //x,y为不相同的类型 报错 两种不同的内部类型

    必须:

    template <class T, class U>
    T GetMin (T a, U b)
    {
    return (a<b?a:b);
    }


    int i,j;
    long l;
    i = GetMin<int,long> (j,l); //或者i = GetMin (j,l);

    Class Template

    通常是使用模板作为类成员变量的类型

    1 Example:

    
    
    template <class T>
    class mypair
    {
    T values [2];
    public:
    mypair (T first, T second) //内联函数
    {

    values[0]=first; values[1]=second;
    }
    };

    mypair<int> myobject (115, 36);               //这样使用
    mypair<double> myfloats (3.0, 2.18);


    2 成员函数为非内联函数

    
    
    template <class T>
    class mypair {
    T a, b;
    public:
    mypair (T first, T second)
    {a=first; b=second;}
    T getmax ();
    };

    template <class T> //增加此声明
    T mypair<T>::getmax ()

    {
    T retval;
    retval = a>b? a : b;
    return retval;
    }

    int main () {
    mypair <int> myobject (100, 75);
    cout << myobject.getmax();
    return 0;
    }

    模板类成员函数外部定义方法:

    
    
    template <class T>
    T mypair<T>::getmax ()

    模板特化 Template Specialization

    1 将模板类转化为特定类型相关的类

    
    
    // class template:
    template <class T>

    class mycontainer
    {
    T element;
    public:
    mycontainer (T arg) {element=arg;}
    T increase () {return ++element;}
    };

    // class template specialization:
    template <> //
    class mycontainer <char> //将其特例化为char型
    {

    char element;
    public:
    mycontainer (char arg) {element=arg;}
    char uppercase ()
    {
    if ((element>='a')&&(element<='z'))
    element+='A'-'a';
    return element;
    }
    };

    int main () {
    mycontainer<int> myint (7);
    mycontainer<char> mychar ('j');
    cout << myint.increase() << endl;
    cout << mychar.uppercase() << endl;
    return 0;
    }
    
    
    template <class T> class mycontainer { ... }; //模板类
    template <> class mycontainer <char> { ... }; //特例化为char型
    template <> class mycontainer <int> { ... }; //特例化为int型


    模板来与之相应的特例化的类之间,并不是什么继承关系,

    所以在特例化一个模板类时,需要将其所有的包含成员进行重写,可以进行扩展。

     

    2 非模板类型参数 Non-type parameters for templates

     

    template <class T, int N>             //int N
    class mysequence

    {
    T memblock [N];
    public:
    void setmember (int x, T value);
    T getmember (int x);
    };

    template <class T, int N>
    void mysequence<T,N>::setmember (int x, T value)
    {
    memblock[x]=value;
    }

    template <class T, int N>
    T mysequence<T,N>::getmember (int x)
    {
    return memblock[x];
    }

    int main () {
    mysequence <int,5> myints;
    mysequence <double,5> myfloats;
    myints.setmember (0,100);
    myfloats.setmember (3,3.1416);
    cout << myints.getmember(0) << '\n';
    cout << myfloats.getmember(3) << '\n';
    return 0;
    }


    可以设置模板类型的缺省值:

    
    
    template <class T=char, int N=10> class mysequence {..};

    mysequence<> myseq; //可以缺省使用
    mysequence<char,10> myseq; //等同于上面


    四 Templates and multiple-file projects

      From the point of view of the compiler, templates are not normal functions or classes.

    They are compiled on demand, meaning that the code of a template function is

    not compiled until an instantiation with specific template arguments is required.

    At that moment, when an instantiation is required, the compiler generates a function specifically

    for those arguments from the template.

    1 模板不会在代码编译的时候直接进行编译,而是在被实例化一个特定类型的模板时候,才会编译到,生成一个特定参数的函数。

    When projects grow it is usual to split the code of a program in different source code files.

    In these cases, the interface and implementation are generally separated.

    Taking a library of functions as example, the interface generally consists of

    declarations of the prototypes of all the functions that can be called.

    These are generally declared in a "header file" with a .h extension,

    and the implementation (the definition of these functions) is in an independent file with c++ code.
      
    Because templates are compiled when required, this forces a restriction

    for multi-file projects: the implementation (definition) of a template class

    or function must be in the same file as its declaration.

    That means that we cannot separate the interface in a separate header file,

    and that we must include both interface and implementation in any file that uses the templates.


    由于模板特殊的编译需要,模板类的定义和函数实现必须在同一个文件中进行。


    Since no code is generated until a template is instantiated when required,

    compilers are prepared to allow the inclusion more than once of the same

    template file with both declarations and definitions in a project without generating linkage errors.


    五 typename

    定义一个模板使用的关键字:classtypename

    在定义作为模板的时候:classtypename,作用是一样的。

    使用typename,实际上也是为模板服务的,在某些情况下我们需要明确的指出某些变量为模板。

    1 在一个模板类中使用另一个模板类定义一个变量时

    
    
    template<typename T>
    struct first
    {
    typedef T * pointer;
    };
    template<typename T>
    class second
    {
    first<T>::pointer p; // syntax error (VC++中 并不报错)
    };

     In a template, the name of a member of another class that depends on

    its template parameter(s) (first<T>::pointer in this example, dependent

    on the T parameter) is a dependent name that is not looked-up immediately.

    To tell the compiler that it is meant to refer to a type and not some other sort of member,

    you must add the keyword typename before it.

    typename 能够在:依赖类型中,typename用来声明一个依赖于另一个模板类参数的嵌套类型。

  • 相关阅读:
    express中session的基本使用
    MongoDB 索引 和 explain 的使用
    MongoDB 数据库创建删除、表(集合) 创建删除、数据增删改查
    node fs模块
    k30s刷入国际rom
    基于webpack项目的全局变量
    nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)
    html手写板
    vue常用配置
    vue组件库从创建到发行和使用
  • 原文地址:https://www.cnblogs.com/bastard/p/2271237.html
Copyright © 2011-2022 走看看