C++模板详细整理
来源:互联网 发布:淘宝买药 货到付款 编辑:程序博客网 时间:2024/06/06 04:29
C++模板
1 模板的概念
模板 字面意思和模型相似,造一个东西,总会有一个模型为基础。如果以后有什么改动,也要在模型的基础上改在。 这么想,大家都知道了 c++里模板也一样也是模型,那这个模型有什么用呢 。
例如,我们希望编写一个函数来比较俩个值,并指出第一个值,是小于?还是大于?还是等于,第二个值。在以前,我们可能想要定义多个函数,每个函数比较一种特定的类型的值。我们会写个重载函数:
int compare(const string &v1,const string &v2){ if(v1<v2) return 1; if(v2<v1) return -1; return 0;}int compare(const double&v1,const double &v2){ if(v1<v2) return 1; if(v2<v1) return -1; return 0;}
这两个函数几乎相同,唯一的差异就是参数类型不同,函数体则完全相同。
如果对每种希望比较的类型都不得不重复定义完全一样的函数体,是非常容易出错的 。甚至让人崩溃(在我以前不知道模板的时候)
但是模板出现后,就大大不一样了,很方便,用法也很简单。接下来学习简单的函数模板。
1.1 函数模板
我们可以定义一个通用的函数模板,而不是为每个类型定义一个新函数。一个函数模板就是一个模型一个公式,可以生成特定类型的函数版本。compare模板可以像这样定义。
template <typename T>int compare (const T &v1 , const T &v2){ if(v1<v2)return 1; if(v2<v1)return -1; return 0;}
1.1.1 函数模板的格式:
template <class 形参名,class 形参名,......> 返回类型 函数名(参数列表) { 函数体 }
其中template和class,没错,他两是一样的。在这里typename 和class没区别
以关键字 template开始,后面跟一个模板参数列表。用< >包围起来。
1.1.2 实例化函数模板
当我们调用一个函数模板时候,编译器 用 函数的实参 来为我们推断 模板的实参类型。比如,我们调用上面的compar时候,编译器就知道自己的模板参数T是什么类型了。
cout << compare(1,0)<<endl; //T为 int类型
实参类型是 int 编译器会推断出模板实参 为 int ,并将它绑定到模板参数 T 上。
接着,编译器根据 他自己推断出的 模板参数 来为我们 实例化一个特定的函数,(就专门为你制定的哦)。
当编译器实例化一个模板时,她会使用实际的模板参数 代替 对应的模板参数 来创建出模板的一个新实例。
例如 :
//实例化出 int comnpare (const int &, const int &)cout <<compare (1 , 0) << endl; //T 为 int//实例化出 int compare(const vector<int>&,const //vector<int>& vector<int> vec{1,2,3},vwc2{4,5,6}; cout <<compare(vec1,vec2)<<endl; // T为 vector<int>
编译器会实例化两个不同的 compare。
1.2 类模板
类模板 是用来生成类的蓝图的,与函数模板不同的地方是,编译器不能为类模板推断模板参数类型。 除非有额外的信息,接下来会说到。
定义类模板
1.2.1、类模板的格式为: template<class 形参名,class 形参名,…> class 类名 { ... };
类似函数模板,类模板以关键字 template 开始,后面跟模板参数列表。在类模板及其中的成员,我们将模板参数当做替身,代替使用模板的时候,用户需要提供类型 或 值。
以下是一些例子 大家参考一下。
// ClassTemplate.htemplate<typename T1,typename T2>class myClass{private: T1 I; T2 J;public: myClass(T1 a, T2 b);//Constructor void show();};//这是构造函数//注意这些格式template <typename T1,typename T2>myClass<T1,T2>::myClass(T1 a,T2 b):I(a),J(b){}//这是void show();template <typename T1,typename T2>void myClass<T1,T2>::show(){ cout<<"I="<<I<<", J="<<J<<endl;}
// Test.cpp#include<iostream>#include"ClassTemplate.h"using std::cout;using std::endl;void main(){ myClass<int,int> class1(3,5); class1.show(); myClass<int,char> class2(3,"a"); class2.show(); myClass<double,int> class3(2.9,10); class3.show(); system("PAUSE");}
1.2.1 类模板和函数模板,都是以template开始,后接模板形参列表组成。模板形参不能为空,一但声明了类模板就可以用类模板的形参名,声明类中的成员变量和成员函数。即可以在类中使用内置类型的地方都可以使用模板形参名来声明。比如
template<class T> class A { public: T a; T b; T hy(T c, T &d); };//在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。
1.2.3
类模板对象的创建:比如一个模板类A,则使用类模板创建对象的方法为A< i n t > m;在类A后面跟上一个<>尖括号并在里面填上相应的类型,这样的话类A中凡是用到模板形参的地方都会被int 所代替。当类模板有两个模板形参时创建对象的方法为A < int, double > m;类型之间用逗号隔开。
1.2.4
对于类模板,模板形参的类型必须在类名后的尖括号中明确指定。比如A< 2 > m;用这种方法把模板形参设置为int是错误的(编译错误:error C2079: ‘a’ uses undefined class ‘A< int >’),类模板形参不存在实参推演的问题。也就是说不能把整型值2推演为int 型传递给模板形参。要把类模板形参调置为int 型必须这样指定A< int > m。
1.2.5
在类模板外部定义成员函数的方法为:
template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体},
比如有两个模板形参T1,T2的类A中含有一个void h()函数,则定义该函数的语法为:
template<class T1,class T2> void A<T1,T2>::h(){}
注意:当在类外面定义类的成员时template后面的模板形参应与要定义的类的模板形参一致。
1.2.6
再次提醒注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。
- C++模板详细整理
- C++模板详细整理2
- C / C++ 文件文件夹操作详细整理
- [模板]详细设计说明书(整理版)【申明:来源于网络】
- 模板整理
- 模板整理---大数模板
- 【整理】Eclipse注释模板
- 排序模板(整理)
- 网站模板整理
- Templat 模板(整理)
- ECshop模板机制整理
- NOIP 考前模板整理
- 图论模板整理
- 模板整理之KMP
- ACM模板整理
- 【整理】Eclipse注释模板
- 背包整理模板
- 高斯消元模板整理
- Electron 屏幕截图
- 51nod 1296 有限制的排列 【动态规划】
- java写入文件的几种方法分享
- zookeeper客户端
- WebService CXF调试常见报错及解决方案
- C++模板详细整理
- Android面试
- itk中的毛刺去除算法
- 2017中国VR体验创新大会报名时间
- Java与算法(6)
- PowerManager.WakeLock
- Git系统学习记录(三) --github远程仓库
- 简单十招提高jQuery执行效率
- 图标分享网站