前言:模板(template)是一个将数据类型参数化的工具。模板分为函数模板和类模板两种。
类模板与函数模板的区别:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化
必须由程序员在程序中显式地指定。函数模板允许隐式调用和显式调用而类模板只能显示调用
函数模板:用于生成函数的模板,可以不说明某些参数的数据类型。编译时,编译器会根据函数模板的使用情况创建出函数名相同,参数类型又用户指定的若干函数。
通过函数模板创建的函数拥有相同的函数体,但函数的参数类型不同。
函数模板的使用:
函数模板使用前必须先声明定义,建议声明定义在头文件中。
函数模板的声明:
template<typename T> <=>template<class T>
返回类型 函数名(参数列表);//T表示任意类型,参数的类型和返回值都可以指定为T
函数模板的定义:
template<typename T>
返回类型 函数名(参数列表)
{
//函数体
函数模板的特化:
函数模板的特化是指在实例化函数模板时,对特定类型的实参进行特殊处理;如当实参为特定类型时,通过函数模板生成的函数会有不同的函数体。
特化需要为函数模板添加新的定义,方式:
template<>
返回类型 函数名<特定的参数类型>(参数列表)
{
//函数体
}
类模板:用于生成类的模板。在编译阶段,编译器会根据类模板的使用情况创建出仅部分成员数据类型和部分成员函数的参数类型不同,但其他完全相同的若干类。
类模板使用:
类模板声明://声明在头文件中,T表示任何类型,由用户指定:
template<typename T ...>
class 类名
{
//成员
}
类模板成员函数的定义://建议写在头文件
template<typename T ...>
返回类型 类名<T,...>::成员函数名(形参列表)
{
//函数体
main.cpp
myarray.h
类模板的偏特化:
特化会指定所有的泛型,偏特化指定部分泛型。
偏特化类模板是需要对整个类模板进行声明定义:
template<typename T,不需要特化的泛型...>
class 类名<指定类型,...,不需要特化的泛型名,...>
{
//类成员
};
类模板与函数模板的区别:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化
必须由程序员在程序中显式地指定。函数模板允许隐式调用和显式调用而类模板只能显示调用
函数模板:用于生成函数的模板,可以不说明某些参数的数据类型。编译时,编译器会根据函数模板的使用情况创建出函数名相同,参数类型又用户指定的若干函数。
通过函数模板创建的函数拥有相同的函数体,但函数的参数类型不同。
函数模板的使用:
函数模板使用前必须先声明定义,建议声明定义在头文件中。
函数模板的声明:
template<typename T> <=>template<class T>
返回类型 函数名(参数列表);//T表示任意类型,参数的类型和返回值都可以指定为T
函数模板的定义:
template<typename T>
返回类型 函数名(参数列表)
{
//函数体
}
实例:
compare.h
#ifndef _COMPARE_H_
#define _COMPARE_H_
template<typename T>
bool isEqual(T i,T j);
template<typename T>
bool isEqual(T i,T j)
{
return i == j;
}
#endif
main.cpp#include "compare.h"
using namespace std;
int main(int argc, char *argv[])
{
isEqual(1,1);
isEqual(1.2f,2.3f);
return 0;
}
函数模板的特化:
函数模板的特化是指在实例化函数模板时,对特定类型的实参进行特殊处理;如当实参为特定类型时,通过函数模板生成的函数会有不同的函数体。
特化需要为函数模板添加新的定义,方式:
template<>
返回类型 函数名<特定的参数类型>(参数列表)
{
//函数体
}
类模板:用于生成类的模板。在编译阶段,编译器会根据类模板的使用情况创建出仅部分成员数据类型和部分成员函数的参数类型不同,但其他完全相同的若干类。
类模板使用:
类模板声明://声明在头文件中,T表示任何类型,由用户指定:
template<typename T ...>
class 类名
{
//成员
}
类模板成员函数的定义://建议写在头文件
template<typename T ...>
返回类型 类名<T,...>::成员函数名(形参列表)
{
//函数体
}
main.cpp
#include "myarray.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
MyArray <int> arr;//<int>中的int可以是任何数据类型
int i = 0;
for(i=0;i<10;i++)
{
arr.addval(i);
}
for(i=0;i<10;i++)
{
cout << arr.index(i) << endl;
}
return 0;
}
myarray.h
#ifndef _MYARRAY_H_
#define _MYARRAY_H_
template<typename T>
class MyArray
{
private:
T data[20];
int len;
public:
MyArray();
T index(int index);
void addval(T val);
};
template <typename T>
MyArray<T>::MyArray()
:len(0){}
template <typename T>
T MyArray<T>::index(int index)
{
return data[index];
}
template <typename T>
void MyArray<T>::addval(T val)
{
data[len] = val;
len++;
}
#endif
类模板的偏特化:
特化会指定所有的泛型,偏特化指定部分泛型。
偏特化类模板是需要对整个类模板进行声明定义:
template<typename T,不需要特化的泛型...>
class 类名<指定类型,...,不需要特化的泛型名,...>
{
//类成员
};
pair.h
#ifndef _PAIR_H_
#define _PAIR_H_
#include <iostream>
using namespace std;
class Pair
{
private:
T1 first;
T2 second;
public:
Pair();
};
template <typename T1,typename T2>
Pair<T1,T2>::Pair()
{
cout << "Pair<T1,T2>::Pair()" << endl;
}
template <typename T2>
class Pair<char,T2>
{
public:
Pair();
};
template <typename T2>
Pair<char,T2>::Pair()
{
cout << "Pair<char,T2>::Pair()" << endl;
}
#endif
main.cpp
#include "pair.h"
int main(int argc, char *argv[])
{
Pair<int,char> pair1;
Pair<char,int> Pair2;
return 0;
}