c++ templates_c++templates pdf - CSDN
精华内容
参与话题
  • C++ Templates中文版电子书pdf下载

    千次阅读 2019-03-14 23:52:04
    C++ Templates下载链接: https://pan.baidu.com/s/1Sp5RwnIJaJCPRlyvimVfgw 提取码获取方式:关注下面微信公众号,回复关键字:1166

    C++ Templates下载链接:

    https://pan.baidu.com/s/1Sp5RwnIJaJCPRlyvimVfgw

    提取码获取方式:关注下面微信公众号,回复关键字:1166

    展开全文
  • C++:模板总结

    万次阅读 多人点赞 2019-03-16 12:34:26
    写在前面     &...模板(Template)指C++程序设计设计...模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成...

    写在前面

            模板(Template)指C++程序设计设计语言中采用类型作为参数的程序设计,支持通用程序设计。C++ 的标准库提供许多有用的函数大多结合了模板的观念,如STL以及IO Stream。模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。

    模板是一种对类型进行参数化的工具;

    通常有两种形式:函数模板和类模板;

    函数模板 针对仅参数类型不同的函数;
    类模板 针对仅数据成员和成员函数类型不同的类。

    使用模板的目的就是能够让程序员编写与类型无关的代码。

    1.函数模板

     template <class 形参名,class 形参名,......> 
     返回类型 函数名(参数列表)
    
       {
    
          函数体
    
       }
    

    其中template和class是关键字,class可以用typename 关键字代替,在这里typename 和class没区别,<>括号中的参数叫模板形参,模板形参和函数形参很相像,模板形参不能为空。一但声明了模板函数就可以用模板函数的形参名声明类中的成员变量和成员函数,即可以在该函数中使用内置类型的地方都可以使用模板形参名。模板形参需要调用该模板函数时提供的模板实参来初始化模板形参,一旦编译器确定了实际的模板实参类型就称他实例化了函数模板的一个实例。比如swap的模板函数形式为

          template <class T> void swap(T& a, T& b){}

    当调用这样的模板函数时类型T就会被被调用时的类型所代替,比如swap(a,b)其中a和b是int 型,这时模板函数swap中的形参T就会被int 所代替,模板函数就变为swap(int &a, int &b)。而当swap(c,d)其中c和d是double类型时,模板函数会被替换为swap(double &a, double &b),这样就实现了函数的实现与类型无关的代码。

    注意:对于函数模板而言不存在 h(int,int) 这样的调用,不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用实参推演来进行,即只能进行 h(2,3) 这样的调用,或者int a, b; h(a,b)。

    2.类模板

    1、类模板的格式为:

        template<class  形参名,class 形参名,…>
        class 类名{ ... };
    

    类模板和函数模板都是以template开始后接模板形参列表组成,模板形参不能为空,一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。比如

        template<class T> class A
        {
           public: 
           T a;
           T b; 
           T hy(T c, T &d);
           };
    

    在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。

    2、类模板对象的创建:比如一个模板类A,则使用类模板创建对象的方法为A m;在类A后面跟上一个<>尖括号并在里面填上相应的类型,这样的话类A中凡是用到模板形参的地方都会被int 所代替。当类模板有两个模板形参时创建对象的方法为A<int, double> m;类型之间用逗号隔开。

    3、对于类模板,模板形参的类型必须在类名后的尖括号中明确指定。比如A<2> m;用这种方法把模板形参设置为int是错误的(编译错误:error C2079: ‘a’ uses undefined class ‘A’),类模板形参不存在实参推演的问题。也就是说不能把整型值2推演为int 型传递给模板形参。要把类模板形参调置为int 型必须这样指定A m。

    4、在类模板外部定义成员函数的方法为:

    template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体}
    

    比如有两个模板形参T1,T2的类A中含有一个void h()函数,则定义该函数的语法为:

        template<class T1,class T2> void A<T1,T2>::h(){}

    注意:当在类外面定义类的成员时template后面的模板形参应与要定义的类的模板形参一致。

    5、再次提醒注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。

    3.模板的非类型形参

    1 、非类型模板形参:模板的非类型形参也就是内置类型形参,如template<class T, int a> class B{};其中int a就是非类型的模板形参。

    2、 非类型形参在模板定义的内部是常量值,也就是说非类型形参在模板的内部是常量。

    3、 非类型模板的形参只能是整型,指针和引用,像double,String, String **这样的类型是不允许的。但是double &,double *,对象的引用或指针是正确的。

    4、 调用非类型模板形参的实参必须是一个常量表达式,即他必须能在编译时计算出结果。

    5 、注意:任何局部对象,局部变量,局部对象的地址,局部变量的地址都不是一个常量表达式,都不能用作非类型模板形参的实参。全局指针类型,全局变量,全局对象也不是一个常量表达式,不能用作非类型模板形参的实参。

    6、 全局变量的地址或引用,全局对象的地址或引用const类型变量是常量表达式,可以用作非类型模板形参的实参。

    7 、sizeof表达式的结果是一个常量表达式,也能用作非类型模板形参的实参。

    8 、当模板的形参是整型时调用该模板时的实参必须是整型的,且在编译期间是常量,比如template <class T, int a> class A{};如果有int b,这时A<int, b> m;将出错,因为b不是常量,如果const int b,这时A<int, b> m;就是正确的,因为这时b是常量。

    9 、非类型形参一般不应用于函数模板中,比如有函数模板template<class T, int a> void h(T b){},若使用h(2)调用会出现无法为非类型形参a推演出参数的错误,对这种模板函数可以用显示模板实参来解决,如用h<int, 3>(2)这样就把非类型形参a设置为整数3。显示模板实参在后面介绍。

    10、 非类型模板形参的形参和实参间所允许的转换
          1、允许从数组到指针,从函数到指针的转换。如:template <int *a> class A{}; int b[1]; A m;即数组到指针的转换
          2、const修饰符的转换。如:template<const int *a> class A{}; int b; A<&b> m; 即从int *到const int *的转换。
          3、提升转换。如:template class A{}; const short b=2; A m; 即从short到int 的提升转换
          4、整值转换。如:template class A{}; A<3> m; 即从int 到unsigned int的转换。
          5、常规转换。

    4.类模板的默认模板类型形参

    1、可以为类模板的类型形参提供默认值,但不能为函数模板的类型形参提供默认值。函数模板和类模板都可以为模板的非类型形参提供默认值。

    2、类模板的类型形参默认值形式为:template<class T1, class T2=int> class A{};为第二个模板类型形参T2提供int型的默认值。

    3、类模板类型形参默认值和函数的默认参数一样,如果有多个类型形参则从第一个形参设定了默认值之后的所有模板形参都要设定默认值,比如templateclass A{};就是错误的,因为T1给出了默认值,而T2没有设定。

    4、在类模板的外部定义类中的成员时template 后的形参表应省略默认的形参类型。比如template<class T1, class T2=int> class A{public: void h();}; 定义方法为template<class T1,class T2> void A<T1,T2>::h(){}。

    5.模板的实例化

    总结一下,C++只有模板显式实例化(explicit instantiation),隐式实例化(implicit instantiation),特化(specialization,也译作具体化,偏特化)。首先考虑如下模板函数代码:

    [cpp] view plaincopyprint?
    template <typename T>  
    void swap(T &a, T &b){  
    ...  
    }  
    

    1.隐式实例化
    我们知道,模板函数不是真正的函数定义,他只是如其名提供一个模板,模板只有在运行时才会生成相应的实例,隐式实例化就是这种情况:

    [cpp] view plaincopyprint?
    int main(){  
        ....  
        swap<int>(a,b);  
        ....  
    }  
    

    它会在运行到这里的时候才生成相应的实例,很显然的影响效率
    这里顺便提一下swap(a,b);中的是可选的,因为编译器可以根据函数参数类型自动进行判断,也就是说如果编译器不不能自动判断的时候这个就是必要的;

    2.显式实例化

    前面已经提到隐式实例化可能影响效率,所以需要提高效率的显式实例化,显式实例化在编译期间就会生成实例,方法如下:

    [cpp] view plaincopyprint?
    template void swap<int>(int &a,int &b);  
    

    这样就不会影响运行时的效率,但编译时间随之增加。

    3.特化

    这个swap可以处理一些基本类型如long int double,但是如果想处理用户自定义的类型就不行了,特化就是为了解决这个问题而出现的:

    [cpp] view plaincopyprint?
    template <> void swap<job>(job a,job b){...}  
    

    其中job是用户定义的类型.

    6.模板的特化(具体化)和偏特化

    类模板:

    测试代码如下:
    
    #include <iostream>
    using namespace std;
    template<typename T1,typename T2>
    class Test{
    public:
        Test(T1 i,T2 j):a(i),b(j){cout<<"模板类"<<endl;}
    private:
        T1 a;
        T2 b;
    };
    template<>   //全特化,由于是全特化,参数都指定了,参数列表故为空。
    class Test<int ,char>{
    public:
        Test(int i,char j):a(i),b(j){cout<<"全特化"<<endl;}
    private:
        int a;
        int b;
    };
    template<typename T2> //由于只指定了一部分参数,剩下的未指定的需在参数列表中,否则报错。
    class Test<char,T2>{
    public:
        Test(char i,T2 j):a(j),b(j){cout<<"个数偏特化"<<endl;}
    private:
        char a;
        T2 b;
    };
    template<typename T1,typename T2> //这是范围上的偏特化
    class Test<T1*,T2*>{
    public:
        Test(T1* i,T2* j):a(i),b(j){cout<<"指针偏特化"<<endl;}
    private:
        T1* a;
        T2* b;
    };
    template<typename T1,typename T2>//同理这也是范围上的偏特化
    class Test<T1 const,T2 const>{
    public:
        Test(T1 i,T2 j):a(i),b(j){cout<<"const偏特化"<<endl;}
    private:
        T1 a;
        T2 b;
    };
    int main()
    {
        int a;
        Test<double,double> t1(0.1,0.2);
        Test<int,char> t2(1,'A');
        Test<char,bool> t3('A',true);
        Test<int*,int*> t4(&a,&a);
        Test<const int,const int> t5(1,2);
        return 0;
    }
    

    运行结果截图:
    在这里插入图片描述
    函数模板:
    而对于函数模板,却只有全特化,不能偏特化:

    #include <iostream>
    using namespace std;
    //模板函数
    template<typename T1,typename T2>
    void fun(T1 a,T2 b){
        cout<<"模板函数"<<endl;
    }
    //全特化
    template<>
    void fun(int a,char b){
        cout<<"全特化"<<endl;
    }
    //函数不存在偏特化,以下代码是错误的
    /*
    template<typename T2>
    void fun(char a,T2 b){
        cout<<"偏特化"<<ednl;
    }
    */
    int main()
    {
        int a=0;
        char b='A';
        fun(a,a);
        fun(a,b);
        return 0;
    }
    

    运行截图如下:
    在这里插入图片描述

    7.模板类的继承

    模板类的继承包括四种:

    1.(普通类继承模板类)

    2.(模板类继承了普通类(非常常见))

    3.(类模板继承类模板)

    4.(模板类继承类模板,即继承模板参数给出的基类)

    其中,普通类继承模板类比较简单,如

    1 template<class T>
    2 class TBase{
    3     T data;
    4 ……
    5 };
    6 class Derived:public TBase<int>{
    7 ……
    8 };
    

    模板类继承普通类:

    1 class TBase{
    2 ……
    3 };
    4 template<class T>
    5 class TDerived:public TBase{
    6 T data;
    7 ……
    8 };
    

    类模板继承类模板:

     1 template<class T>
     2 class TBase{
     3 T data1;
     4 ……
     5 };
     6 template<class T1,class T2>
     7 class TDerived:public TBase<T1>{
     8 T2 data2;
     9 ……
    10 };
    
    1. 模板类继承模板参数给出的基类
      ——继承哪个基类由模板参数决定
    #include<iostream>
    using namespace std;
    
    
    class BaseA{
    public:
        BaseA(){cout<<"BaseA founed"<<endl;}
    };
    
    class BaseB{
    public:
        BaseB(){cout<<"BaseB founed"<<endl;}
    };
    
    template<typename T, int rows>
    class BaseC{
    private:
        T data;
    public:
        BaseC():data(rows){
            cout<<"BaseC founed "<< data << endl;}
    };
    
    template<class T>
    class Derived:public T{
    public:
        Derived():T(){cout<<"Derived founed"<<endl;}
    };
    
    
    void main()
    {
        Derived<Base A> x;// BaseA作为基类
        Derived<Base B> y;// BaseB作为基类
        Derived<Base C<int, 3> > z; // BaseC<int,3>作为基类
        
    

    模板实例化问题:

            在我们使用类模板时,只有当代码中使用了类模板的一个实例的名字,而且上下文环境要求必须存在类的定义时,这个类模板才被实例化。

    1.声明一个类模板的指针和引用,不会引起类模板的实例化,因为没有必要知道该类的定义。

    2.定义一个类类型的对象时需要该类的定义,因此类模板会被实例化。

    3.在使用sizeof()时,它是计算对象的大小,编译器必须根据类型将其实例化出来,所以类模板被实例化.

    4.new表达式要求类模板被实例化。

    5.引用类模板的成员会导致类模板被编译器实例化。

    6.需要注意的是,类模板的成员函数本身也是一个模板。标准C++要求这样的成员函数只有在被调用或者取地址的时候,才被实例化。用来实例化成员函数的类型,就是其成员函数要调用的那个类对象的类型

    展开全文
  • c++ templates 中文版》

    千次阅读 2013-07-14 12:13:48
    c++为了兼容以前的class,也可以用class代替模板,但是不建议这么使用,因为模板参数并不一定是自定义类型,也可以是内置类型(基本类型)。 template//template 也可以 T AddFun(T a,T b) { return a+b; }

    第二章 函数模板

    关于typename与class

     typename是随着模板产生的,所以产生较晚。c++为了兼容以前的class,也可以用class代替模板,但是不建议这么使用,因为模板参数并不一定是自定义类型,也可以是内置类型(基本类型)。

    template<typename T>//template<class T> 也可以
    
    T AddFun(T a,T b)
    
    {
    
         return a+b;
    
    }


    关于c++文件类型: 头文件: h,hpp,hxx.实现文件:c,cc,cpp.


    展开全文
  • C++ Templates - The Complete Guide ,既是C++template 教科书,也是C++template 的详尽参考手册。此文件为文字版pdf,可直接选择文字复制(文字的不分高不高清,都是高清)
  • C++ templates之“模板的模板参数”

    千次阅读 2018-11-10 20:05:05
    定义:指一个模板,它本身的参数类型就是模板,在英语原文中是“template template parameter”。 例如:template&lt;typename T1, template&lt;typename T2&gt; class CONT&...

    定义:指一个模板,它本身的参数类型就是模板,在英语原文中是“template template parameter”。

    例如:template<typename T1,   template<typename T2> class CONT>,就是将template参数类型声明中的一个(原本应该是typename T2)替换成template<typename T2> class CONT

    关键点:

    1. 在模板的模板参数中,class(指上面例子中标红色的class) 不能被替换成typename。在模板中,如果不能区分的哪应该使用typename和class,可以全部都用class替代,typename和class的作用基本相同,而typename出现得比较晚。同时它也支持缺省值。

    • 例:template<typename T1,   template<typename T2> class CONT>  class A{.........}            // 正确
    •        template<typename T1,   template<typename T2> typename CONT>  class A{.........}            // 错误
    •        template<typename T1,   template<class T2> class CONT>  class A{.........}            // 正确
    •        template<typename T1,   template<typename T2> typename CONT=std::list>  class A{.........}   //正确

    2.以上面的例子为例,在使用第二个参数,必须是一个模板类。

    3.函数模板不支持模板的模板参数。

    • 例:template<template<typename T> class CONT>  void func{.........}          //错误

    4.在模板中,可以前面的模板参数声明可以被后面的使用。

    • 例:template<typename T1, 
    •                         template<typename T2, typename ALLOC=std::allocator<T2> > class CONT=std::list
    • class A{.........}          //假设T1和T2的类型一样,那T2可以用T1替代(当然类型不一样也可以,只要容器空间分配不                                                     出问题)。同时,如果T2没用的话可以省略不写。

    5.函数定义

    • 例:template<typename T1,   template<typename T2> typename CONT=std::list
    • class A{     void func();  .........}
    • template<typename T1,   template<typename T2> typename CONT=std::list
    • void A<T1,/*list*/>::func(){.....}     //如果使用编译器(Qt)自动生成定义的话,会报错,因为没有此行中红色标注的

    6.要了解重载解析的相关内容,尤其是二义性和演绎部分。

    展开全文
  • C++ Templates(简体中文版).pdf

    千次下载 热门讨论 2020-06-11 23:30:17
    C++ Templates(简体中文版).pdf
  • c++ 模板的优点和缺点

    千次阅读 2011-11-09 13:09:01
    Templates in C++ - Pros and Cons By SergeyChepurin | 29 Oct 2011 C++WindowsIntermediate Advantages and drawbacks of usingtemplates in C++ projects Licence CPOL First Posted 29Oct 2011 Views...
  • Eclipse c++注释模板以及注释文档生成

    千次阅读 2012-07-23 11:17:10
    首先注释可以使用中文,主要目的是为了让其他人看懂。 注释可以通过eclipse模板设置进行规范:Windows---preferences---C/C++----...首先设置相关模板输入,Windows-preferences-C/C++-Editor-Templates,加入自定义
  • error: template with C linkage

    万次阅读 2012-08-28 13:56:49
    当编译C/C++混用的项目时,可能会遇到这个问题。 1.某个头文件中extern “C”的使用存在问题,如果包含这个有问题的头文件之后,又包含,等就会出现这个问题。  1). 需要检查extern "C"后面为一个函数
  • Dev C++初始化(默认)代码修改方法

    万次阅读 2016-03-12 12:39:13
    有没有为每次创建C++ project的默认代码感觉到烦扰?如果你用Dev C++只是用于编写竞赛算法,如果每次同样的...1.1找到你安装Dev C++的安装路径下Templates,我的是默认安装路径C:\Program Files (x86)\Dev-Cpp\Templ
  • template只在c++中存在。 解决方法是注释掉QTSS.h 中的extern "C" { 和 }  在StreamingServer工程中,QTSSRTSPProtocol.h中也有extern "c" {…OSHeader.h…},同样去掉extern部分   <br /> 
  • Templates(模板)和 Generic Programming(泛型编程)作者:Scott Meyers译者:fatalerror99 (iTePubs Nirvana)发布:http://blog.csdn.net/fatalerror99/C++ templatesC++ 模板)的最初动机是直截了当的:使得...
  • C++按位写入/读取文件

    千次阅读 2018-04-14 10:13:34
    #include&lt;fstream&gt; #include&lt;string&gt; #include&lt;iostream&gt; using namespace std; int main() { ofstream 输出文件("test.bin"... int leng...
  • 贡献15本经典C、C++、MFC、VC++教程,都是pdf完整版的 2011-12-11 16:35:49| 分类: Linux资料库 | 标签:c、c++、mfc、vc++ |字号 订阅 C++ Primer第三版(中文pdf高清完美版,1043页) C++实例教程(pdf版...
  • C++0x漫谈》系列

    万次阅读 2007-09-25 13:33:00
    05年开始关注C++0x,其时C++0x的大部分草案其实都已经初具雏形。但几个重大的特性:concepts, rvalue, memory-model, variadic-templates等都还在激烈的动荡当中。于是一路看着这些特性不断成长,不断出revisions。...
  • 我现在再看《C++ Templates》,看到P197。有一个例子不是很懂,求解释,具体如下: template <typename C> class List<void* C::*>{ public: typedef void* C::*ElementType; ... //其他的我省略了...
  • VS2011可以下载了,VC++部分强大了很多

    千次阅读 2012-06-17 22:41:59
    VS2011现在可以通过这个链接下载 ... 我会在这周末对VC++部分的改进进行说明:) 注:MSFT同志们,括号内吐cao请直接忽略 Building Metro-style applications with C++ by Usi
  • C++11 变参模板(variadic templates)

    千次阅读 2018-05-26 11:55:26
    Variadic Template是C++11的一个很重要的特性;变体现在两个方面:(1)参数个数:利用参数个数逐一递减的特性,实现递归调用;(2)参数类型:参数个数逐一递减导致参数类型也逐一递减;两个注意点(1)递归调用(2...
  • C++ Template The Complete Guide(C++模板完全指引)引言 引言 我将推出系列博客翻译《C++ Template The Complete Guide (second edition)》,原版封面如下: 同时在翻译的过程中,我会配合C++ Actor framework(CAF...
  • 让Qt5默认支持C++17的设置方法

    千次阅读 2019-04-25 22:04:15
    单个项目的设置方法 打开项目的pro文件,将CONFIG += console ...找到Qt5的安装目录,我的安装目录是在D盘Qt5.12.3文件夹下,打开如下目录:D:\Qt5.12.3\Tools\QtCreator\share\qtcreator\templates\wizards\projec...
1 2 3 4 5 ... 20
收藏数 18,771
精华内容 7,508
关键字:

c++ templates