本文学习内容参考: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. HW4.6

    public class Solution { public static void main(String[] args) { final double MILES_PER_KILOGRAM = 1 ...

  2. unexpected error ConnectionError object has no attribute

    unexpected error ConnectionError object has no attribute

  3. ldconfig及 LD_LIBRARY_PATH

    dconfig及 LD_LIBRARY_PATH 1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library ...

  4. Linq to SQL 简单增删改查

    用Linq大大减少了对数据库的一般操作所需的编码量.运行下面事例之前,首先建一个叫做Alien的数据库表. CREATE TABLE [dbo].[Aliens](    [Id] [int] IDE ...

  5. IIS7错误:“Web服务器被配置为不列出此目录的内容”的解决办法

    IIS7错误:“Web服务器被配置为不列出此目录的内容”的解决方法: 在"操作"下,点启用,此按钮将变成禁用,则可消除此错误

  6. &lt;ASP.NET4 从入门到精通&gt;学习笔记3

    第三部分,状态管理与缓存 何为状态管理.起始对于web而言.经过前面章节的解说.已经理解,对于web程序,就是一个无状态的程序.每次的请求与每次的响应,两者之间本身就是独立存在的,这一点对于早期的静态 ...

  7. Building and setting up QT environment for BeagleBone

    There are too few information available on how to easily setup QT environment for building Beaglebon ...

  8. NIO学习:使用Channel、Buffer写入文件

    NIO的效率要高于标准IO,因为NIO将最耗时的IO操作(填充和提取缓冲区)转移会操作系统.NIO以块为单位传输数据,相比标准IO的以字节为单位效率要高很多. 通道和缓冲时NIO的核心对象,每个NIO ...

  9. 转:ORACLEERP开发基础之EBS开发基础

    转自:http://blog.itpub.net/8781091/viewspace-1012244/ [内容导航] 第1页:开发工具安装 第2页:增加数据块 第3页:注册表单FORM 第4页:注册请 ...

  10. oracle EBS中使用PLSQL提交"关闭离散"并发请求

    declare l_request_id number; l_return_flag boolean; l_num_user_id number; l_num_resp_id number; l_nu ...