C++模板详解
C++模板实例化之隐式实例化、显示实例化、显示调用、隐式调用和模板特化详解模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程。
对于函数模板而言,模板实例化之后,会生成一个真正的函数。
而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始化。
模板的实例化分为隐式实例化和显示实例化。
对函数模板的使用而言,分为两种调用方式,一种是显示模板实参调用(显示调用),一种是隐式模板实参调用(隐式调用)。
对于类模板的使用而言,没有隐式模板实参和显式模板实参使用的说法,因为类模板的使用必须显示指明模板实参。
各个概念请勿混淆。
1.隐式实例化1.1模板隐式实例化的定义这是相对于模板显示实例化而言。
在使用模板函数和模板类时,不存在指定类型的模板函数和模板类的实体时,由编译器根据指定类型参数隐式生成模板函数或者模板类的实体称之为模板的隐式实例化。
1.2函数模板隐式实例化函数模板隐式实例化指的是在发生函数调用的时候,如果没有发现相匹配的函数存在,编译器就会寻找同名函数模板,如果可以成功进行参数类型推演,就对函数模板进行实例化。
还有一种简介调用函数的情况,也可以完成函数模板的实例化。
所谓的简介调用是指将函数入口地址传给一个函数指针,通过函数指针完成函数调用。
如果传递给函数指针不是一个真正的函数,那么编译器就会寻找同名的函数模板进行参数推演,进而完成函数模板的实例化。
参考如下示例。
#include<iostream>usingnamespace std;template<typename T>void func(T t){cout<<t<<endl;}void invoke(void (*p)(int)){int num=10;p(num);}int main(){invoke(func);}程序成功运行并输出10。
1.3类模板隐式实例化类模板隐式实例化指的是在使用模板类时才将模板实例化,相对于类模板显示实例化而言的。
考察如下示例程序。
#include<iostream>usingnamespace std;template<typename T>class A{T num;public:A(){num=T(6.6);}void print(){cout<<"A'num:"<<num<<endl;}};int main(){A<int> a; //显示模板实参的隐式实例化a.print();}程序输出结果:A'num:6。
2.显示实例化2.1模板显示实例化的定义显示实例化也称为外部实例化。
在不发生函数调用的时候讲函数模板实例化,或者在不适用类模板的时候将类模板实例化称之为模板显示实例化。
2.2函数模板的显示实例化对于函数模板而言,不管是够发生函数调用,都可以通过显示实例化声明将函数模板实例化,格式为:template函数返回类型函数模板名<实际类型列表>(函数参数列表)例如:template void func<int>(const int&);2.3类模板的显示实例化对于类模板而言,不管是否生成一个模板类的对象,都可以直接通过显示实例化声明将类模板实例化,格式为:template class类模板名<实际类型列表>例如:template class theclass<int>;3.函数模板调用方式3.1隐式模板实参调用在发生函数模板的调用时,不显示给出模板参数而经过参数推演,称之为函数模板的隐式模板实参调用(隐式调用)。
如:template<typename T>void func(T t){cout<<t<<endl;}func(5);//隐式模板实参调用3.2显示模板实参调用在发生函数模板的调用时,显示给出模板参数而不需要经过参数推演,称之为函数模板的显示模板实参调用(显示调用)。
显示模板实参调用在参数推演不成功的情况下是有必要的。
考察如下程序。
#include<iostream>usingnamespace std;template<typename T>T Max(const T&t1,const T&t2){return (t1>t2)?t1:t2;}int main(){int i=5;//cout<<Max(i,'a')<<endl;//无法通过编译cout<<Max<int>(i,'a')<<endl;//显示调用,通过编译}直接采用函数调用Max(I,’a’)会产生编译错误,因为i和’a’具有不同的数据类型,无法从这两个参数中进行类型推演。
而采用Max<int>(i,’a’)调用后,函数模板的实例化不需要经过参数推演,而函数的第二个实参也可以由char转换为int型,从而成功完成函数调用。
编程过程中,建议采用显示模板实参的方式调用函数模板,这样提高了代码的可读性,便于代码的理解和维护。
4.模板特化4.1模板特化的定义模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。
模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。
4.2函数模板特化函数模板特化是在一个统一的函数模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本。
查看如下例子。
#include<iostream>usingnamespace std;template<typename T>T Max(T t1,T t2){return (t1>t2)?t1:t2;}typedefconstchar* CCP;template<>CCP Max<CCP>(CCP s1,CCP s2){return (strcmp(s1,s2)>0)?s1:s2;}int main(){//调用实例:int Max<int>(int,int)int i=Max(10,5);//调用显示特化:const char* Max<const char*>(const char*,const char*)constchar* p=Max<constchar*>("very","good");cout<<"i:"<<i<<endl;cout<<"p:"<<p<<endl;}程序正常编译运行结果:i:10p:very在函数模板显示特化定义(Explicit Specialization Definition)中,显示关键字template 和一对尖括号<>,然后是函数模板特化的定义。
该定义指出了模板名、被用来特化模板的模板实参,以及函数参数表和函数体。
在上面的程序中,如果不给出函数模板Max<T>在T为const char*时的特化版本,那么在比较两个字符串的大小时,比较的是字符串的起始地址的大小,而不是字符串的内容在字典序中先后次序。
4.2.1使用函数重载替代函数模板特化除了定义函数模板特化版本外,还可以直接给出模板函数在特定类型下的重载形式(普通函数)。
使用函数重载可以实现函数模板特化的功能,也可以避免函数模板的特定实例的失效。
例如,把上面的模板特化可以改成如下重载函数。
typedefconstchar* CCP;CCP Max(CCP s1,CCP s2){return (strcmp(s1,s2)>0)?s1:s2;}程序运行结果和使用函数模板特化相同。
但是,使用普通函数重载和使用模板特化还是有不同之处,主要表现在如下两个方面:(1)如果使用普通重载函数,那么不管是否发生实际的函数调用,都会在目标文件中生成该函数的二进制代码。
而如果使用模板的特化版本,除非发生函数调用,否则不会在目标文件中包含特化模板函数的二进制代码。
这符合函数模板的“惰性实例化”准则。
(2)如果使用普通重载函数,那么在分离编译模式下,应该在各个源文件中包含重载函数的申明,否则在某些原文件中就会使用模板实例化,而不是重载函数。
4.3类模板特化类模板特化类似于函数模板的特化,即类模板参数在某种特定类型下的具体实现。
考察如下代码。
#include<iostream>usingnamespace std;template<typename T>class A{T num;public:A(){num=T(6.6);}void print(){cout<<"A'num:"<<num<<endl;}};template<>class A<char*>{char* str;public:A(){str="A' special definition ";}void print(){cout<<str<<endl;}};int main(){A<int> a1; //显示模板实参的隐式实例化a1.print();A<char*> a2;//使用特化的类模板A2.print();}程序输出结果如下:A'num:6A' special definition。
c中模板的定义 -回复
c中模板的定义-回复C语言中的模板(template)是一种在编程过程中用于生成代码的机制。
它允许开发人员编写可重用的代码模块,能够自动适应不同的数据类型,并生成相应的代码。
在本文中,我们将详细介绍C语言中模板的定义以及其在编程中的应用。
首先,我们来了解一下C语言中模板的概念。
模板是一种用于生成代码的蓝图或者规范。
它定义了一种通用的代码结构,其中可以包含占位符或参数,以便在生成代码时可以替换为具体的值或类型。
通过使用模板,我们可以实现代码的复用和泛化,从而提高开发效率和代码质量。
在C语言中,我们可以使用宏(macro)来定义模板。
宏是一种宏处理器指令,它可以用来扩展代码或者生成代码。
C语言中的宏定义以“#define”开头,接着是宏的名称和定义。
通过使用宏,我们可以将代码中的一些通用部分定义为宏,然后在需要的时候进行替换。
不过,C语言中的宏定义虽然可以实现简单的模板功能,但是它有一些局限性。
宏定义只能进行简单的文本替换,而无法对类型和表达式进行处理。
为了解决这个问题,C语言引入了泛型编程(generic programming)的概念,通过使用宏和一些特殊的语法来实现模板。
C语言中的泛型编程主要依靠预处理器(preprocessor)的功能来实现。
预处理器是一种在编译之前对源代码进行处理的程序,它可以根据一些特定的规则来进行文本替换。
通过使用预处理器的宏定义,在C语言中我们可以模拟出一些泛型的特性。
我们可以通过宏定义来创建一个通用的模板,它可以接受不同类型的参数,并生成对应的代码。
例如,我们可以定义一个通用的打印函数模板:#define PRINT(x) printf("d", x)这个宏定义可以用来打印任意类型的变量。
在使用时,我们只需要将要打印的变量作为参数传递给PRINT宏即可。
这样,宏展开时会将参数x替换为具体的值,并生成相应的打印代码。
除了宏定义之外,C语言中还有其他实现模板的方法。
C 模板定义
C+=模板定义1、模板的概念:在C++中,模板是泛型编程的基础。
模板是创建类或函数的蓝图或公式。
2、定义函数模板:模板定义以template关键字开始,后接模板形参表(用<>括起来),多个模板形参用逗号隔开。
模板形参的名字没有实际意义。
1)模板形参表:模型形参可以是表示类型的类型形参,也可以是表示常量表达式的非类型形参。
模板形参表不能为空。
2)使用模板函数:使用时,编译器会确定绑定到模板形参的模板实参类型。
编译器确定用实际类型代替每个类型形参,用值代替每个非类型形参。
3)inline函数模板:如,template <type T> T max(const T&, const T&);模板函数定义和使用示例:#include <iostream>using std::cout;using std::endl;//定义模板函数template <typename T>int compare(const T &v1, const T &v2){if(v1<v2) return -1;if(v2<v1) return 1;return 0;}//使用模板函数int main(){cout<<compare(1,2)<<endl;cout<<compare("a","A")<<endl;system("pause");return 0;}3、定义类模板在类声明前加上template <class T>,其余部分与类的声明基本一致。
类模板可以定义数据成员、函数成员和类型成员,构造函数和析构函数等。
也可以使用标号控制对成员的访问。
在类和类的成员中,可以使用模板形参作为类型或值的占位符,在使用类时再提供那些类型或值。
C++模板详解(一)
C++模板详解(⼀)C++模板 模板是C++⽀持参数化多态的⼯具,使⽤模板可以使⽤户为类或者函数声明⼀种⼀般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。
模板是⼀种对类型进⾏参数化的⼯具; 通常有两种形式:函数模板和类模板; 函数模板针对仅参数类型不同的函数; 类模板针对仅数据成员和成员函数类型不同的类。
使⽤模板的⽬的就是能够让程序员编写与类型⽆关的代码。
⽐如编写了⼀个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型⽆法实现,要实现这些类型的交换就要重新编写另⼀个swap函数。
使⽤模板的⽬的就是要让这程序的实现与类型⽆关,⽐如⼀个swap模板函数,即可以实现int 型,⼜可以实现double型的交换。
模板可以应⽤于函数和类。
下⾯分别介绍。
注意:模板的声明或定义只能在全局,命名空间或类范围内进⾏。
即不能在局部范围,函数内进⾏,⽐如不能在main函数中声明或定义⼀个模板。
⼀、函数模板通式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)。
c中模板的定义 -回复
c中模板的定义-回复C中的模板(Template)是一种强大且重要的工具,它使得代码的重用性和可维护性大大提高。
模板是一种在编译时进行代码生成的机制,允许在静态类型语言中编写通用代码。
在本文中,我将详细介绍C中模板的定义以及如何使用它。
首先,让我们了解什么是模板。
在C语言中,模板是一种用于生成通用代码的机制。
它允许我们定义一种通用的数据类型、函数或类,以便在编译时根据传入的参数生成特定类型的代码。
例如,考虑一个用于交换两个变量的函数。
如果我们只想在整数或浮点数之间交换变量,我们可以编写一个具体的函数来实现它。
但是,当我们需要在其他类型之间交换变量时,我们就不得不为每种类型都编写一个新的函数。
这显然是低效的,并且导致了代码的重复。
使用模板,我们可以定义一种通用的交换函数,该函数可以适用于任何类型的变量。
我们只需将变量的类型作为参数传递给模板,编译器将自动生成适用于该特定类型的代码。
下面是一个展示交换函数模板的示例:template <typename T>void swap(T& a, T& b) {T temp = a;a = b;b = temp;}在这个例子中,`typename T`是在模板函数中定义的类型参数。
我们可以将任何类型的变量作为参数传递给这个函数模板,并且编译器将根据参数的类型生成相应的代码。
这种通用性使得我们可以在不同的数据类型之间进行交换,而无需重写一个新的函数。
要使用模板函数,我们只需将要交换的变量作为参数传递给它,例如:int main() {int x = 5, y = 10;swap(x, y); 调用交换函数模板float a = 2.5, b = 7.8;swap(a, b); 再次调用交换函数模板return 0;}在上面的代码中,我们分别调用了两次交换函数模板来交换整数和浮点数。
除了函数模板之外,C中还可以定义类模板。
类模板允许我们定义通用的类,并在编译时生成特定类型的类。
C++模板常用功能讲解
C++模板常⽤功能讲解前⾔泛型编程是C++继⾯向对象编程之后的⼜⼀个重点,是为了编写与具体类型⽆关的代码。
⽽模板是泛型编程的基础。
模板简单来理解,可以看作是⽤宏来实现的,事实上确实有⼈⽤宏来实现了模板类似的功能。
模板,也可以理解为模具⾏业的模型。
根据分类,有函数模板和类模板。
根据传⼊的不同模板参数,函数模板会⽣成不同模板函数。
类模板则⽣成不同的模板类。
模板参数1. 概念模板定义以关键字template开始,<>中是模板参数列表(template parameter list),模板参数列表即表⽰可以是⼀个或多个模板参数(template parameter)。
模板实参则是在实例化函数模板或是类模板时的类型或值。
模板形参是通过模板实参推导出来的或是直接显式指定。
模板参数和普通函数参数⼀样,可以有默认值参数。
2. 模板形参分类类型参数(type parameter) 表明这个模板参数是⼀个类型。
template<class/typename T, ……>⾮类型参数(nontype parameter) 表明这个模板参数不是⼀个类型,⽽是常量数值,只能是整形、指针和引⽤。
template<int N, ……>template<class/typename T, int N, ……>// 例template<const int* pM>void Test1(){}template<const char M>void Test2(){int nArr[M] = {0};}class A{};template<A& AA>void Test3(){}const int n = 4;extern const int arr[] = {1, 2, 3};A a;int _tmain(int argc, _TCHAR* argv[]){Test1<arr>();Test2<n>();Test3<a>();return0;}3. 模板实参模板实参推断(template argument deduction) 编译器使⽤函数调⽤中的实参类型来推断出模板实参,然后⽤这些实参⽣成对应的函数。
C++中模板(Template)详解及其作用介绍
C++中模板(Template)详解及其作⽤介绍⽬录概述函数模板类模板模板类外定义成员函数类库模板抽象和实例概述模板可以帮助我们提⾼代码的可⽤性, 可以帮助我们减少开发的代码量和⼯作量.函数模板函数模板 (Function Template) 是⼀个对函数功能框架的描述. 在具体执⾏时, 我们可以根据传递的实际参数决定其功能. 例如: int max(int a, int b, int c){a = a >b ? a:b;a = a > c ? a:c;return a;}long max(long a, long b, long c){a = a >b ? a:b;a = a > c ? a:c;return a;}double max(double a, double b, double c){a = a >b ? a:b;a = a > c ? a:c;return a;}写成函数模板的形式:template<typename T>T max(T a, T b, T c){a = a >b ? a:b;a = a > c ? a:c;return a;}类模板类模板 (Class Template) 是创建泛型类或函数的蓝图或公式.#ifndef PROJECT2_COMPARE_H#define PROJECT2_COMPARE_Htemplate <class numtype> // 虚拟类型名为numtypeclass Compare {private:numtype x, y;public:Compare(numtype a, numtype b){x=a; y=b;}numtype max() {return (x>y)?x:y;};numtype min() {return (x < y)?x:y;};};mian:int main() {Compare<int> compare1(3,7);cout << compare1.max() << ", " << compare1.min() << endl;Compare<double> compare2(2.88, 1.88);cout << compare2.max() << ", " << compare2.min() << endl;Compare<char> compare3('a', 'A');cout << compare3.max() << ", " << compare3.min() << endl;return 0;}输出结果:7, 32.88, 1.88a, A模板类外定义成员函数如果我们需要在模板类外定义成员函数, 我们需要在每个函数都使⽤类模板. 格式: template<class 虚拟类型参数>函数类型类模板名<虚拟类型参数>::成员函数名(函数形参表列) {}类模板:#ifndef PROJECT2_COMPARE_H#define PROJECT2_COMPARE_Htemplate <class numtype> // 虚拟类型名为numtypeclass Compare {private:numtype x, y;public:Compare(numtype a, numtype b);numtype max();numtype min();};template<class numtype>Compare<numtype>::Compare(numtype a,numtype b) {x=a;y=b;}template<class numtype>numtype Compare<numtype>::max( ) {return (x>y)?x:y;}template<class numtype>numtype Compare<numtype>::min( ) {return (x>y)?x:y;}#endif //PROJECT2_COMPARE_H类库模板类库模板 (Standard Template Library). 例如:#include <vector>#include <iostream>using namespace std;int main() {int i = 0;vector<int> v;for (int i = 0; i < 10; ++i) {v.push_back(i); // 把元素⼀个⼀个存⼊到vector中}for (int j = 0; j < v.size(); ++j) {cout << v[j] << " "; // 把每个元素显⽰出来}return 0;}输出结果:0 1 2 3 4 5 6 7 8 9抽象和实例到此这篇关于C++中模板(Template)详解及其作⽤介绍的⽂章就介绍到这了,更多相关C++模板内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
c 中模板使用详解(转)写得非常棒赞~第四维空间c 博客
C++中模板使用详解(转)——写得非常棒,赞~ - 第四维空间- C++博客C++中模板使用详解(转)——写得非常棒,赞~1. 模板的概念。
我们已经学过重载(Overloading),对重载函数而言,C++的检查机制能通过函数参数的不同及所属类的不同。
正确的调用重载函数。
例如,为求两个数的最大值,我们定义MAX()函数需要对不同的数据类型分别定义不同重载(Overload)版本。
//函数1.int max(int x,int y);{return(x>y)?x:y ;}//函数2.float max( float x,float y){return (x>y)? x:y ;}//函数3.double max(double x,double y){return (c>y)? x:y ;}但如果在主函数中,我们分别定义了char a,b; 那么在执行max(a,b);时程序就会出错,因为我们没有定义char类型的重载版本。
现在,我们再重新审视上述的max()函数,它们都具有同样的功能,即求两个数的最大值,能否只写一套代码解决这个问题呢?这样就会避免因重载函数定义不全面而带来的调用错误。
为解决上述问题C++引入模板机制,模板定义:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数,从而实现了真正的代码可重用性。
模版可以分为两类,一个是函数模版,另外一个是类模版。
2. 函数模板的写法函数模板的一般形式如下:Template <class或者也可以用typename T>返回类型函数名(形参表){//函数定义体}说明:template是一个声明模板的关键字,表示声明一个模板关键字class不能省略,如果类型形参多余一个,每个形参前都要加class <类型形参表>可以包含基本数据类型可以包含类类型.请看以下程序://Test.cpp#include <iostream>using std::cout;using std::endl;//声明一个函数模版,用来比较输入的两个相同数据类型的参数的大小,class也可以被typename代替,//T可以被任何字母或者数字代替。
C#设计模式——模板方法(TemplateMethod)
C#设计模式——模板⽅法(TemplateMethod)⼀、概述在软件开发中,对某⼀项操作往往有固定的算法结构,⽽具体的⼦步骤会因为不同的需要⽽有所不同。
如何可以在稳定算法结构的同时来灵活应对⼦步骤变化的需求呢?⼆、模板⽅法模板⽅法是⼀种常见的设计模式,它定义⼀个操作中的算法的⾻架,⽽将⼀些步骤延迟到⼦类中。
模板使得⼦类可以不改变⼀个算法的结构即可重定义该算法的某些特定步骤。
模板⽅法的结构图如下AbstractClass是抽象类,定义了抽象的操作ConcreteClass实现了抽象操作中与⼦类相关的特定步骤。
三、⽰例在这⾥以实现⼀个公司的薪资系统为例介绍⼀下模板⽅法的应⽤。
⾸先定义抽象类,⼀般建议将抽象的操作定义为⾮虚public⽅法,将⼦类需要定义的特定步骤定义为抽象的protected⽅法。
1 publicabstractclass Employee2 {3 publicvoid GetSalary()4 {5 GetBasicSalary();6 AddBonus();7 }89 protectedabstractvoid GetBasicSalary();10 protectedabstractvoid AddBonus();11 }接着分别实现经理和CEO的薪资1 publicclass Manager : Employee2 {3 protectedoverridevoid GetBasicSalary()4 {5 Console.WriteLine("Get Manager Basic Salary");6 }78 protectedoverridevoid AddBonus()9 {10 Console.WriteLine("Add Manager Bonus");11 }12 }1314 publicclass CEO : Employee15 {16 protectedoverridevoid GetBasicSalary()17 {18 Console.WriteLine("Get CEO Basic Salary");19 }2021 protectedoverridevoid AddBonus()22 {23 Console.WriteLine("Add CEO Bonus");24 }25 }。
c 模板的实现原理
c 模板的实现原理
C模板的实现原理是通过预处理器和编译器进行完成的。
在C 语言中,模板的实现主要是通过宏定义和宏展开来实现的。
首先,在C语言中,我们可以使用宏定义来定义一个通用的模板。
这个模板可以包含参数,通过使用特定的占位符表示。
例如,我们可以定义一个通用的泛型数组类型:
```c
#define ARRAY(T) struct { T* data; int size; }
```
这里的T就是我们的参数,表示数组元素的类型。
通过定义这个宏,我们可以根据不同的类型来创建相应的数组类型。
例如,我们可以使用ARRAY(int)来定义一个整型数组类型。
接下来,当我们使用这个宏进行编译时,预处理器会将宏展开为相应的代码。
例如,当我们使用ARRAY(int)时,预处理器会将宏展开为:
```c
struct { int* data; int size; }
```
预处理器会将宏展开到所有使用这个宏的地方,从而生成相应的代码。
然后,编译器会对展开后的代码进行编译和优化,生成最终的
可执行文件。
总结起来,C模板的实现原理是通过预处理器进行宏展开来实现的。
预处理器会根据定义的宏来替换相应的代码。
这样就可以根据不同的参数,生成不同的代码,实现泛型编程的效果。
C++函数模板与类模板实例解析
C++函数模板与类模板实例解析本⽂针对C++函数模板与类模板进⾏了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解。
具体内容如下:泛型编程(Generic Programming)是⼀种编程范式,通过将类型参数化来实现在同⼀份代码上操作多种数据类型,泛型是⼀般化并可重复使⽤的意思。
泛型编程最初诞⽣于C++中,⽬的是为了实现C++的STL(标准模板库)。
模板(template)是泛型编程的基础,⼀个模板就是⼀个创建类或函数的蓝图或公式。
例如,当使⽤⼀个vector这样的泛型类型或者find这样的泛型函数时,我们提供⾜够的信息,将蓝图转换为特定的类或函数。
⼀、函数模板⼀个通⽤的函数模板(function template)就是⼀个公式,可⽤来⽣成针对特定类型或特定值的函数版本。
模板定义以关键字template开始,后⾯跟⼀个模板参数列表,列表中的多个模板参数(template parameter)以逗号分隔。
模板参数表⽰在类或函数定义中⽤到的类型或值。
1、类型参数⼀个模板类型参数(type parameter)表⽰的是⼀种类型。
我们可以将类型参数看作类型说明符,就像内置类型或类类型说明符⼀样使⽤。
类型参数前必须使⽤关键字class 或typename:template <typename T> // typename和class⼀样的T function(T* p){T tmp = *p; // 临时变量类型为T//...return tmp; // 返回值类型为T}关键字typename和class是⼀样的作⽤,但显然typename⽐class更为直观,它更清楚地指出随后的名字是⼀个类型名。
编译器⽤模板类型实参为我们实例化(instantiate)特定版本的函数,⼀个版本称做模板的⼀个实例(instantiation)。
当我们调⽤⼀个函数模板时,编译器通常⽤函数实参来为我们推断模板实参。
