本文学习内容参考:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html

C++模板

1.模板分为函数模板类模板两种类型

  函数模板针对参数类型不同的函数

  类模板针对数据成员成员函数类型不同的类;

  使用模板的目的就是能够让程序员编写与类型无关的代码。比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个swap模板函数,即可以实现int 型,又可以实现double型的交换。

  注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板;

2.函数模板的通用格式如下:

template <class 形参名, class 形参名,......> 返回类型   函数名(参数列表)
{
函数体
}

  其中templateclass 是关键字,这里的class也可以用 typename 关键字来代替。<>中的参数叫做模板形参模板形参不能为空。一旦声明了模板函数,就可以用模板函数的形参名声明函数中的成员,即在该函数中使用内置类型的地方都可以使用模板形参名。模板函数在调用时,通过模板函数的实参来初始化模板形参,一旦编译器确定了实际的模板实参类型就称他实例化了函数模板的一个实例。下面以swap的模板函数为例:

template <class T> void swap(T& a, T& b){};

  当调用这样的模板函数时,这里的类型 就会被调用时的类型所替代。比如swap(a , b),当 a 和 b 是 int 时,模板函数swap中的形参 T 就会被 int 所替代,模板函数就变为了swap(int& a, int& b)。而当swap(a , b)中的 a 和 b 为 double 类型时,模板函数就相应地变为了swap(double& a, double& b)。这样也就实现了代码与类型无关。

  Demo: 求两个数的最大值的模板函数

#include<iostream>
using namespace std; template <typename T>
const T& max(const T& a, const T& b)
{
return a > b ? a : b;
} int main()
{
cout << max(2.1, 3.3) << endl; //模板实参被隐式推演为double类型
cout << max<double>(2.1, 3.3) << endl; //显示指定实参类型为double
cout << max<int>(2.1, 3.3) << endl; //显示指定实参类型为int
system("pause");
return ;
}

result:

3.类模板的通用格式如下:

template <class 形参名, class 形参名......> class 类名
{
..........
};

  3.1类模板和函数模板都是以template开始后接模板形参列表组成,模板形参不能为空,一但声明了类模板就可以用类模板的形参名声明类中的成员变量和成员函数,即可以在类中使用内置类型的地方都可以使用模板形参名来声明。

template <class T>
class Demo
{
  T a;
public:
  Demo(T first);
  T GetValue();
};

  3.2类模板的成员函数在类外面实现的定义方式如下(需要在每个方法的实现前面添加 template<class T>):

template <class T>
Demo<T>::Demo(T first){
a=first;
} template <class T>
T Demo<T>::GetValue(){
return a;
}

4.模板特殊化(Template Specialization)(此处学习内容参考http://blog.csdn.net/fingding/article/details/32079289)

  4.1模板的特殊化是当模板中的pattern有确定的类型时,模板有一个具体的实现。例如假设我们的类模板pair 包含一个取模计算(module operation)的函数,而我们希望这个函数只有当对象中存储的数据为整型(int)的时候才能工作,其他时候,我们需要这个函数总是返回0。这可以通过下面的代码来实现:

#include<iostream>
using namespace std; template<class T>
class Pair
{
T value1;
T value2;
public:
Pair(T first, T second)
{
value1 = first;
value2 = second;
}
T Module() { return ; }
}; template<>
class Pair<int>
{
int value1;
int value2;
public:
Pair(int first, int second) {
value1 = first;
value2 = second;
}
int Module();
};

//template<>          //此处正常情况下需要,但是在VS2015中编译的结果如下result11
int Pair<int>::Module() {
return value1%value2;
} int main()
{
Pair<int> p1(, );
Pair<float> p2(5.5, 2.3);
cout << p1.Module() << endl;
cout << p2.Module() << endl;
system("pause");
return ;
}

  result11:

>------ 已启动生成: 项目: Template specialization, 配置: Debug Win32 ------
> TemplateMain.cpp
>c:\users\administrator\documents\visual studio \projects\suanfa\shiyan1\test1--sequence\template specialization\templatemain.cpp(): error C2910: “Pair<int>::Module”: 无法显式专用化
>c:\users\administrator\documents\visual studio \projects\suanfa\shiyan1\test1--sequence\template specialization\templatemain.cpp(): warning C4305: “参数”: 从“double”到“float”截断
========== 生成: 成功 个,失败 个,最新 个,跳过 个 ==========

  以上的错误:error C2910  提示无法显示专用化,查询C2910错误代码,解决方案:去掉函数Module()实现时前面的 template<>即可;

  可以学习到很多关于生成与错误处理知识的链接:https://msdn.microsoft.com/zh-cn/library/z7kx322x.aspx

  修改后的运行结果如下:

5.非类型形参示例(参考:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html)

  该示例实现的是让用户亲自指定栈的大小,并实现栈的相关操作

TemplateDemo.h

#pragma once
template <class T, int MAXSIZE>class Stack { //MAXSIZE由用户创建对象时自行设定
private:
T elements[MAXSIZE]; //包含栈中元素的数组
int numElements; //当前栈中元素的个数
public:
Stack(); //构造函数
void push(T const&); //压入元素
void pop(); //弹出元素
T top() const; //返回栈顶元素
bool Empty() const { //判断栈是否为空
return numElements == ;
}
bool Full() const { //判断栈栈是否已满
return numElements == MAXSIZE;
}
}; template <class T,int MAXSIZE>
Stack<T, MAXSIZE>::Stack() :numElements() { //初始时栈不含任何元素 } template <class T,int MAXSIZE>
void Stack<T, MAXSIZE>::push(T const& elem) {
if (numElements == MAXSIZE)
{
throw std::out_of_range("Stack<>::push():Stack if fulll");
}
elements[numElements] = elem; //将新元素elem添加到栈中
++numElements; //当前栈中元素个数加1
} template <class T,int MAXSIZE>
void Stack<T, MAXSIZE>::pop() {
if (numElements <= )
{
throw std::out_of_range("Stack<>::pop(),Stack is Empty");
}
--numElements; //减少元素个数
} template <class T,int MAXSIZE>
T Stack<T, MAXSIZE>::top() const{
if (numElements <= )
{
throw std::out_of_range("Stack<>::pop(),Stack is Empty");
}
return elements[numElements - ]; //返回最后(栈顶)一个元素
}

TemplateDemo.cpp

#include<iostream>
#include<string>
#include"TemplateDemo.h"
using namespace std;
int main()
{
try
{
Stack<int, > int20Stack; //可以存储20个int类型数据的栈
Stack<int, > int40Stack; //可以存储40个int类型数据的栈
Stack<string, > string40Stack; //可以存储40个string类型数据的栈 //使用存储20个int类型数据的栈
int20Stack.push();
cout << int20Stack.top() << endl;
int20Stack.pop(); //使用可存储40个string类型数据的栈
string40Stack.push("hello");
cout << string40Stack.top() << endl;
string40Stack.pop();
string40Stack.pop();
system("pause");
return ;
}
catch (const std::exception& ex)
{
cerr << "Exception: " << ex.what() << endl;
system("pause");
return EXIT_FAILURE; //退出程序且有error标记
}
}

result:

C++模板学习随笔的更多相关文章

  1. typeScript学习随笔(一)

    TypeScript学习随笔(一) 这么久了还不没好好学习哈这么火的ts,边学边练边记吧! 啥子是TypeScript  TypeScript 是 JavaScript 的一个超集,支持 es6 标准 ...

  2. (转) 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

    特别棒的一篇文章,仍不住转一下,留着以后需要时阅读 基于Theano的深度学习(Deep Learning)框架Keras学习随笔-01-FAQ

  3. C#程序集Assembly学习随笔(第一版)_AX

    ①什么是程序集?可以把程序集简单理解为你的.NET项目在编译后生成的*.exe或*.dll文件.嗯,这个确实简单了些,但我是这么理解的.详细:http://blog.csdn.net/sws8327/ ...

  4. Hive入门学习随笔(一)

    Hive入门学习随笔(一) ===什么是Hive? 它可以来保存我们的数据,Hive的数据仓库与传统意义上的数据仓库还有区别. Hive跟传统方式是不一样的,Hive是建立在Hadoop HDFS基础 ...

  5. JavaScript ES6 数组新方法 学习随笔

    JavaScript ES6 数组新方法 学习随笔 新建数组 var arr = [1, 2, 2, 3, 4] includes 方法 includes 查找数组有无该参数 有返回true var ...

  6. 64位BASM学习随笔(一)

     64位BASM学习随笔(一) Delphi的BASM一直是我最喜爱的内嵌汇编语言,同C/C++的内联汇编相比,它更方便,更具灵活性,由于C/C++的内联汇编仅仅能是或插入式的汇编代码,函数花括号 ...

  7. XTemplate模板学习和使用总结

    XTemplate模板学习和使用总结 前言   XTemplate是我接触的第一个模板语言,用在公司的一个NodeJS项目中,跟它打交道经常是因为需要使用它的语法向模板中注入数据.因为是刚入门前端不久 ...

  8. jquery学习随笔

    转)jquery学习随笔(jquery选择器)   jQuery的选择器是CSS 1-3,XPath的结合物.jQuery提取这二种查询语言最好的部分,融合后创造出了最终的jQuery表达式查询语言. ...

  9. Python学习随笔:使用xlwings设置和操作excel多行多列数据以及设置数据字体颜色填充色对齐方式的方法

    ☞ ░ 前往老猿Python博文目录 ░ 在前面老猿的文章中,<Python学习随笔:使用xlwings读取和操作Excel文件>.<Python学习随笔:使用xlwings读取和操 ...

随机推荐

  1. 8-14-Exercise

    8-14-小练 这次是我这组出题......我出的是B.C.D[虽然本来是想出的很难......╮(╯▽╰)╭但是,没找到AC1000+同时又让我想出的难题......SO...我出的真的不难= =] ...

  2. C++中随机函数

    #include <iostream> using namespace std; #include <stdlib.h> #include <time.h> int ...

  3. 适合高级Java程序员看的12本书

    1.Thinking in Java 2.Head First Java 3.Java in a Nutshell 4.The elements of Java style 5.Effective J ...

  4. 使用dispatch_once:创建单列

    无论是爱还是恨,你都需要单例.实际上每个iOS或Mac OS应用都至少会有UIApplication或NSApplication. 什么是单例呢?Wikipedia是如此定义的: 在软件工程中,单例是 ...

  5. 使用sqlite3 有关tableview删除cell的问题

    在root页面,想要删除tableviewcell,是有一定顺序的 首先要删除 数据库sqlite3 中的数据,然后删除数组中的数据,最后删除cell 一般我们知道,删除cell要在删除数组数据之后, ...

  6. VM启用ISO共享

    在SCVMM中可以启用ISO共享,如下图: 如果不勾选共享镜像复选框,则vmm会把镜像文件通过网络复制到Hyper-v主机下的虚拟机配置文件夹中 配置步骤如下: 1.新建一个共享文件夹(存放ISO), ...

  7. [置顶] linux 解压版安装

    1:下载mysql解压版包去官网下载www.mysq.com 下载.下载linux通用版本就好了 2.基本配置 首先,我们准备好Linux环境,我们使用CentOS 5.8进行试验安装.第一步,我们需 ...

  8. Highcharts简介

    最近要做一个油田油压或温度数据的监控软件,数据会秒级写到数据库中,界面上需要动态展示数据跟随时间变化. 在网上找了很多js插件,希望能够即时高效的展示数据,最终确定了使用Highcharts插件. H ...

  9. java程序查不出数据来

    同样的错误,不可再犯第三次!!! 数据库中是char,里面带空格,但在pl/sql中这样写可以查出来.如下: select ipostid from product t where ipostid= ...

  10. HDU1241(bfs)JAVA

    import java.util.Scanner;public class Main1241 { public static void main(String[] args) { Scanner ci ...