前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++中的模板基础知识小结

C++中的模板基础知识小结

原创
作者头像
fieldli
发布2019-01-18 20:14:17
1.1K0
发布2019-01-18 20:14:17
举报
文章被收录于专栏:大块小屋-技术大块小屋-技术

前言

模板支持哪些类型。主要支持一下类型

假设一个模板类

template <class T>

class Test

{

....

}

class类型:class A ,Struct B.。 如:Test<A> t;

基本类型(int,double,float)如:Test<int> t;

指针类型:X * 如:Test<X*> t;

引用类型:X & 如:Test<X&> t;

const 应用: const X& 如:Test<const X&> t;

函数指针: int (*f) (int ,int) 如:Test<int (*)(int,int)> t;

函数类型:int (int,int) 如:Test<int (int,int)> t;

成员函数:int (X::*memf)(int,int) 如:Test<X::*memf(int,int)> t;

模板类型

类模板

template <class T >;

class A

{

T t;

class B;

}

类模板中,一个注意事项。A 类中有内部类B。

那么在声明类B的时候,要用A<int>::B b;而不能直接 A::B b;

成员函数模板

class B

{

template <class T>;

void fun(T & t);

}

注意模板函数不能是虚的 。

函数模板

template<class T>;

int fun(T t)

{

代码语言:txt
复制
return

}

使用 :funt(int a);

模板默认值

template<class T, int size >

class A

{

T t size

}

A<double ,1> a;

使用时,size 必须是常量 。不能为变量。

模板参数里包含模板

template < class < T1,T2 ,template<class T3> >

class MyMap

{

C<T1> k;

C<T2>v

}

template <class T>

class Test

{

}

使用方式如下:MyMap<string,string,Test<int>> mm;

可变模板参数列表(c+11)

template <class ...T>

fun(T...args)

模板的一些知识点

##模板设置默认类型

template<class T= int >

class Test

{

代码语言:txt
复制
T a;

}

这种方式可以设定模板的默认类型是int型。使用的时候可以直接用 Test<>a;在有些地方看起来比较奇怪。给阅读者带来很大的障碍。

模板的声明与实现必须位于同一个h文件。

##模板参数推导

假设定义模板函数fun。

template <class T>

int fun(T t);

正常使用方法是:

int a =1;

fun<int>(a); //这里已经指定了类型int。

那其实我们还可以写成

fun(a),这里可以看出fun后面的<int> 已经被省略掉了,这是因为通过a可以推导出类型为int。

模板的特化

模板的特化,实际上就是模板的特殊化。假设有一个模板函数compare来比较两个参数中较大的,并返回较大的。函数定义如下:

template<class T>

T compare(T a, T b){

}

对于int,double等可计算数值的我们直接使用即可。如max<int>(a,b)。假设我们现在想处理string类型的呢。string类型的比较与基本类型的比较并不一样,怎么处理呢。这就利用了模板的特殊化机制。即只针对string这种类型的做特殊处理,对于其他的类型还按照通用的处理方法。添加如下定义即可:

template<>

String compare(String a, String b){

代码语言:txt
复制
//方法体内实现个性化处理

}

类似可以实现其他类型的特化。

template<>

char compare (char a,char b) //针对char型的特化。

{

}

##部分特化(偏特化)

在模板特化的小节中,模板参数只有一种。我们来看一下 模板参数有两个的情况。定义如下

template <class T,class P>

int compare( T t, P p ){};

现在我们想让第一个类型T通用,第二个类型P保持特殊化,也就当P为某个类型时做特殊化处理。 假设当P为string类型时做特殊处理。则新增如下定义。

template<T>

int compare(T t,string p){};//对string类型的特殊处理。compare<int,string>(a,b);会调用到此处的实现。

这样看来是不是简单很多,不要被特化,偏特化这些词搞糊涂了。特化就是针对特殊类型做特殊的逻辑处理。偏特化就是对部分类型做特殊的逻辑处理。其他例子如:

template<T> 偏特化模板2

int compare(T t,int ){};//对int类型的特殊处理。

使用 compare<int,int>(a,b);这种就会调用到此处的实现。

##模式特化

前面两节都是针对参数类型来做个性化的实现逻辑。那是否可以针对特殊的模式呢。比如对于指针类型的,对于const类型的做特殊化处理。

template<class T> 偏特化模板2

int compare(T* t){};//对指针类的做个性化的实现

template<class T> 偏特化模板2

int compare(const T&){};//对const& 类型的做特殊的实现。

template<class T>

int compare (vector<T> vec) 对vector类型的做特化处理。

类型萃取

结合模板的特化,很容易进行类型的萃取。萃取实际上是对模板中参数的获取。

template <class T>

struct TypeMap //这个struct 是用来获取T 的类型的。

{

代码语言:txt
复制
type T const& type;

}

template <>

struct TypeMap<int> //特化类型int 的时候,type的值就是int

{

代码语言:txt
复制
type int   type;

}

template <>

struct TypeMap<double> //特化类型double的时候,type的值就是double

{

代码语言:txt
复制
type double   type;

}

现在使用如下:

TypeMap<int>::type返回的就是int类型

TypeMap<double>::type返回的就是double类型

我们可以 用TypeMap<int>::type v;就可以声明一个int型的变量v了。

#后记

此处是特化的一个学习笔记。

模板的一些特性

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 模板类型
    • 类模板
      • 成员函数模板
        • 函数模板
          • 模板默认值
            • 模板参数里包含模板
              • 可变模板参数列表(c+11)
              • 模板的一些知识点
                • 模板的声明与实现必须位于同一个h文件。
                  • 模板的特化
                    • 类型萃取
                    • 模板的一些特性
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                    http://www.vxiaotou.com