在C++的模板体现了一种泛型编程的思想,当我们不确定要传入的参数是何种数据类型时我们可以写一个模板类型来代替,当传入参数时才将类型告诉它。模板也是属于一种静态多态,,模板的不同类型发生在编译时。泛型编程:不是针对某一个具体的类型编程,而是对一类类型进行编程
#include <iostream>
#include <string.h>
using std::endl;
using std::cout;
using std::string;
template <typename T>
T add(T x,T y)
{
cout<<"T add(T x,T y)"<<endl;
return x+y;
}
int add(int x,int y)
{
cout<<"int add(int x,int y)"<<endl;
return x+y;
}
template<>
const char* add<const char*>(const char* x,const char* y)
{
cout<<"const char* add(const char* x,const char* y)"<<endl;
size_t len=strlen(x)+strlen(y)+1;
char* tmp=new char[len]();
strcpy(tmp,x);
strcat(tmp,y);
return tmp;
}
template<typename T=int,short KMin=2>//必须显示实例化,除非加默认值
T multiple(T x, T y)
{
return x*y*KMin;
}
void test()
{
int a=2,b=3;
float a1=1.2,b1=2.3;
string a2="hello",b2="world";
const char* a3="hello";
const char* b3=",world";
cout<<"a+b = "<<add<int>(a,b)<<endl; //显示实例化
cout<<"a1+b1 = "<<add(a1,b1)<<endl; //隐式实例化
cout<<"a2+b2 = "<<add(a2,b2)<<endl;
cout<<"a3+b3 = "<<add(a3,b3)<<endl;
cout<<"multiplr(a,b) = "<<multiple<int,10>(2,3)<<endl;
}
int main()
{
test();
}
需要注意的是:
- 模板的参数类型:
- 类型参数,比如这里的T
- 非类型参数,都是整形(bool/char/short/int/size_t/long/long long/void) 注意:排除了浮点数float(单精度)/double(双精度)
- 对于模板函数而言,不能分成头文件和实现文件分开的形式(不能将声明与实现分开),和内联函数相同 ,否则就会报错,因为在编译完成之后链接不到。如果一定要分成头文件与实现文件,那么可以在头文件中包含实现文件#include "add.cc"
- 模板的特化(将模板的参数以特殊值展示出来)
- 全特化(将所有的模板参数都以特殊形式展示出来
- 部分特化(偏特化)(将模板的参数特化出一部分,至少有一个没有特化)
可变模板参数
性质:
- 要求函数参数包必须唯一,且是函数的最后一个参数;模板参数包则没有
- 当声明一个变量(或标识符)为可变参数时,省略号位于该变量的左侧,为打包
- 当使用参数包时,省略号位于参数名右边,表示展开此参数包,也叫解包
#include <utility>
#include <iostream>
using std::cout;
using std::endl;
using std::pair;
using std::tuple;
//可变模板参数
//Args标识符左侧使用了省略号,在C++11被称为模板参数包,
//表示可以接受任意多个参数作为模板参数,编译器会将多个模板参数打包成“单个”的模板参数包
template<typename...Args> //
void display(Args...args)//args被称为函数参数包,表示函数可以接受多个任意类型的参数
//...args表示将args解包给参数Args
{
//打包
cout<<"sizeof...(Args) = "<<sizeof...(Args)<<endl;
//sizeof...(形参包)其中sizeof...是运算符
cout<<"sizeof...(args) = "<<sizeof...(args)<<endl;
}
//递归解包
void print()
{
cout<<endl;
}
template<typename T,typename ...Args>
void print(T t,Args...args)
{
cout<<t<<" ";
print(args...);
}
int main()
{
display();
display(1,2,3);
print(3,4,5,6,7,8);
}