本文主要参考了C++ Primer 5,模板类和泛型编程
1 背景
模板类产生的背景呢,就是想要创建一个通用的函数模板,模板就和类一样,可以实例化,实例化时不需要任何参考既可以应用char,也可以应用int和double等;
比如:比较int compare(int a,int b)和 函数int compare(double a,double b);
初始想法就是定义多个重载函数的方法;
重载函数,定义的函数除了形参不同,函数内部大体都一样,所以面对这样的问题,有了泛型编程和模板类
对于上面比较大小可以定义一个模板类:
template <typename T>
//初次接触模板类,可能对这种定义方式比较乱;
//简而言之,可以将 T 看出任意一个类型参数 而typename就是定义这是一个模板参数(个人理解,帮助理解,不是严格的定义)
// 定义完之后 T等同于任何一个参数 包括char int double float,class,vector等
//就像搓麻将时候的赖子,typename T 目的就是定义牌面是T的牌可以当赖子
//那么以后打牌时,T可以当任意牌打出;
int compare(const T &v1,const T &v2)
{
if(v1<v2)return -1;
if(v2<v1) return 1;
return 0;
}
官方定义:模板定义是以关键字template开始,后跟一个模板参数列表,这是一个逗号分隔的一个或者多个模板参数的列表,用小于号和大于号包围起来<>;
需要注意的就是:
在模板定义中,模板参数不能为空
上面是使用;
下面是模板的实例化;
比如运行了两行代码
cout<<compare(1,0)<<endl; //T当int
vector<int> v1(1,2,3),v2(2,3,4);
cout<<compare(v1,v2)<<endl; //T为vector
实例化函数模板时
T与形参类型的绑定主要是编译器进行完成的;
例如上面两行代码,当我们调用compare时,编译器使用实参的类型来确定绑定到模板参数T的类型;
编译器会用推断出来得到模板参数来为我们实例化一个特定版本的函数。
针对上面梁行代码,编译器会实例化出两个不同版本的compare。
2 模板类型参数
根据第一节,大致了解了什么是模板函数和什么是模板类型参数,上面也演示了如何进行使用模板类型参数。
下面演示,模板类型参数作为函数返回参数的使用方法:
Template <typename T> T foo(T* p)
{
T tep = *p;
//
return tep;
}
注意:`类型参数前必须使用关键字 class或者typename
如
template <typename T,class U> T calc(const T&,const U&);
2.1 类模板
定义类模板
//树上的一个类模板的定义
template <typename T> Class B
{
public:
typedef T value_type;
typedef typename std::vector<T>::size_type size_type;
//构造函数
B();
B(std::initializer_list<T> Il);
//
size_type size() const {return data->size();}
bool empty() const {return data->empty();
}
void push_back(const T &t)
{data->push_back(t);}
void push_back(T &&t)
{
data->push_back(std::move(t);
}
void pop_back();
//元素访问
T& back();
T& operator[] (size_type i);
private:
std::share_ptr<Std::vector<T> > data;
//
void check(size_type i,const std::string &msg) const;
};
本文探讨了C++中的模板类,旨在提供一个通用的编程解决方案。文章首先介绍了模板类产生的背景,如通过模板避免重载函数的冗余。然后详细阐述了模板类型参数的使用,包括作为函数返回参数的情况,并给出了具体示例。特别是,文章讲解了类模板的定义,展示如何实例化模板类并说明了编译器如何根据实参类型推断模板参数。

1214

被折叠的 条评论
为什么被折叠?



