函数模板

我们可以把函数模板当做一种特殊的函数,里面的参数类型可以是任意类型,这样的话我们就可以减少重复定义,从而让这个函数模板自动适应不同的参数类型,也就是说函数可以适应多种类型的参数,例如doubleint或者类什么的。

C++为了实现上面的功能,引入了template这个概念。我们可以把template当成是一种特殊的类型参数,并且也可以在函数里当做参数传递,心里面把它当做int什么的就行了。

使用类型参数声明函数模板的格式如下所示:

template <class identifier> function_declaration;
template <typename identifier> function_declaration; // 这里使用了typename 当做声明类型参数

上面声明函数模板的格式只有一处不同,那就是classtypename,在这里其实使用哪一种都没有区别,看自己喜欢就行,C++对此也没有做严格的区分;

为了更好的说明如何使用函数模板,便在举一个很形象的例子,那就是一个用来返回较大值的函数,具体写法如下所示:

template <typename T>
T GetMax(T a, T b)
return a > b ? a : b;

在上面的短短几行代码中我们就创建了一个函数模板用来获取两个数之间较大的那个数,不难看出T在这里并没有指明具体的类型,在这我们仍然可以在心里把它当做普通变量处理,返回值也是T。

为了使用我们定义的函数模板,可以参照统一的函数模板调用格式:

 function_name<type> (parameters);    // type就是具体的类型,例如int、double这些,parameters就是函数里的参数,也是具体类型

所以,如果我们想要实现获取两个整形值里较大的那个,我们可以传入int这个类型之后调用GetMax函数,具体示例如下:

int x = 4;
int y = 2; int max = GetMax<int> (x, y); // max = 4

类模板

由于template声明的类型可以是任意类型,也就是使用的时候传入具体的类型就行。所以可以参考上面函数模板的例子构造类模板也是一样的,在使用这个类的时候传入具体的变量类型就行了。例如下面的类模板定义:

template <typename T>
class MyPair{
T value[2]; public:
MyPair(T first, T second)
{
value[0] = first;
value[1] = second;
}
};

类模板的示例代码中定义一个MyPair类,用来存储任意类型的两个元素,例如doublecharint等,下面我就给出两个示例,分别存储doubleint类型的变量

MyPair<int> myInt(2, 3);    // 存储两个整型值
MyPair<double> myDouble(2.3, 3.43); // 存储两个double值

模板类的成员函数也可以在类外定义,写法和函数模板的写法是一样的,具体示例如下所示:

template <class T>
class MyPair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T Getmax ();
}; template <typename T>
T MyPair<T>::Getmax () // 在类外定义函数, 注意前面的写法和函数模板写法一致
{
T retval;
retval = a>b? a : b;
return retval;
}

模板特化

如果我们想要为类模板定义一个不同的实现接口,并且要求需要将特定参数作为参数传递时,那么我们就可以将该模板特化

为了更好地说明模板特化,还是举个简单的例子吧。假设我们定义一个类mycontainer,这个类可以存储一个任意类型的变量,并且这个类还有一个函数叫做increasement用来将存储的类型加一。并且,如果这个类存储的是一个char类型的时候,我们会发现这个类对于实现将其中的成员变量转换为大写的功能将更加方便,不妨将这个函数定义为ToUpper,因此,我们可以为char类型的类模板实现模板特化,具体的示例代码如下:

// 模板特化
#include <iostream>
using namespace std; // 声明类模板:
template <typename T>
class mycontainer {
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
}; // char类型的模板特化:
template <>
class mycontainer<char> {
char element;
public:
mycontainer(char arg) {element=arg;} char ToUpper()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};

对于上面的模板特化,我们需要几点,注意类模板和模板特化的区别和联系

  • 在类模板的前面加上template <>,这表明是模板特化,也就是是说模板特化都需要加上这句话;
  • 还有一点就是类模板后面使用了<char>参数,这个特定参数表示我们将模板类特化程<char>类型;

template的其他用法

除了以template或者class关键字开头声明的表示类型的模板参数之外,template也可以具有其他类型的参数,例如intdouble这些参数,就类似于一个函数中拥有多个参数,每个参数类型还不一样。为了更好的说明template的其他用法,不妨参考下面的示例代码,

#include <iostream>
using namespace std; template<class T, int N> // 这里除了含有class声明的类型之外,还拥有一个int类型
class mysequence {
T memblock [N];
public:
void setmember(int x, T value);
T getmember(int x);
}; template<class T, int N>
void mysequence<T,N>::setmember(int x, T value) {
memblock[x]=value;
} template<class T, int N>
T mysequence<T,N>::getmember(int x) {
return memblock[x];
} int main(){
mysequence<int,5> myints;
mysequence<double,5> myfloats;
myints.setmember(0,100);
myfloats.setmember(3,3.1416);
cout << myints.getmember(0) << '\n';
cout << myfloats.getmember(3) << '\n';
return 0;
}

C++总结之template的更多相关文章

  1. 为.NET Core项目定义Item Template

    作为这个星球上最强大的IDE,Visual Studio不仅仅提供了很多原生的特性,更重要的是它是一个可定制的IDE,比如自定义Project Template和Item Template就是一个非常 ...

  2. jQuery.template.js 简单使用

    之前看了一篇文章<我们为什么要尝试前后端分离>,深有同感,并有了下面的评论: 我最近也和前端同事在讨论这个问题,比如有时候前端写好页面给后端了,然后后端把这些页面拆分成很多的 views, ...

  3. 2000条你应知的WPF小姿势 基础篇<69-73 WPF Freeze机制和Template>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000ThingsYou Should Know About C# 和 2,00 ...

  4. tornado template

    若果使用Tornado进行web开发可能会用到模板功能,页面继承,嵌套... 多页应用模板的处理多半依赖后端(SPA就可以动态加载局部视图),就算是RESTfull的API设计,也不妨碍同时提供部分模 ...

  5. 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)

    今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...

  6. C++泛型编程:template模板

    泛型编程就是以独立于任何特定类型的方式编写代码,而模板是C++泛型编程的基础. 所谓template,是针对“一个或多个尚未明确的类型”所编写的函数或类. 使用template时,可以显示的或隐示的将 ...

  7. 新手入门Underscore.js 中文(template)

    Underscore.js是一个很精干的库,压缩后只有4KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了javaScript的编程.MVC框架Backbone.js就将这个库作为自 ...

  8. knockoutjs如何动态加载外部的file作为component中的template数据源

    玩过knockoutjs的都知道,有一个强大的功能叫做component,而这个component有个牛逼的地方就是拥有自己的viewmodel和template, 比如下面这样: ko.compon ...

  9. JavaScript模板引擎artTemplate.js——template.helper()方法

    上一篇文章我们已经讲到了helper()方法,但是上面的例子只是一个参数的写法,如果是多个参数,写法就另有区别了. <div id="user_info"></d ...

  10. linux下, 再次遇到使用thinkphp的模板标签时,报错used undefined function \Think\Template\simplexml_load_string() 是因为没有安装 php-xml包

    linux下, 使用thinkphp的模板标签,如 eq, gt, volist defined, present , empty等 标签时, 报错: used undefined function ...

随机推荐

  1. [LC] 42. Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  2. hadoop集群搭建(docker)

    背景 目前在一家快递公司工作,因项目需要,对大数据平台做个深入的了解.工欲利其器必先利其器,在网上找了许多教程,然后自己搭建一个本地的环境并记录下来,增加一些印象. 环境搭建 1)Ubuntu doc ...

  3. 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) P-Fear Factoring 区间内数的所有因数的和(除法分块)

    题意就是标题. 思路: 对于每个数 a 算出 1~a 的所有因数和sum(a),输出sum(b)-sum(a-1). 关键在于如何求出 sum. 首先发现因数∈ 1 ≤ i ≤ n ,每个因数在区间[ ...

  4. Nginx笔记总结三:内核参数优化

    net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1800 net.ipv4.ip_conntrack_max = 16777216 ...

  5. Java Servlet XML文件配置

  6. 初窥Android AudioFlinger

    Android  AudioFlinger 是Android音频系统的两大服务之一,另一个服务是AudioPolicyService,这两大服务都在系统启动时有MediaSever加载,加载的代码位于 ...

  7. Android多模块混淆的问题

    Android在多模块或者组件化的时候,关于混淆的管理,一般常见的做法就是两条. 把所有的混淆规则规则都放在app模块下面,由app统一管理.这样就会有一个问题,就是到会导致混淆规则的冗余. 由mod ...

  8. JQUERY的基本使用方法

    #准备工作 在官网下载JQUERY库 将库在你需要的网页上引用 123 <head><script src="jquery.js"></script& ...

  9. 线程sleep,wait,notify,join,yield方法解析

    线程的五种状态 线程从创建到销毁一般分为五种状态,如下图: 1) 新建 当用new关键字创建一个线程时,就是新建状态. 2) 就绪 调用了 start 方法之后,线程就进入了就绪阶段.此时,线程不会立 ...

  10. 自定义Toast的出现样式

    使用下面的方法来获取一个Toast对象: private Toast showShortToast() { if (toast == null) { toast = new Toast(this); ...