C++ 模板

转:http://www.runoob.com/cplusplus/cpp-templates.html

2018-01-05

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。

模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector <int> 或 vector <string>

您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

函数模板

模板函数定义的一般形式如下所示:

template <class type> ret-type func-name(parameter list) { // 函数的主体 }

在这里,type 是函数所使用的数据类型的占位符名称。这个名称可以在函数定义中使用。

下面是函数模板的实例,返回两个数中的最大值:

实例

#include <iostream>
#include <string>
 
using namespace std;
 
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
int main ()
{
 
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
 
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
 
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
 
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World

类模板

正如我们定义函数模板一样,我们也可以定义类模板。泛型类声明的一般形式如下所示:

template <class type> class class-name {
.
.
.
}

在这里,type 是占位符类型名称,可以在类被实例化的时候进行指定。您可以使用一个逗号分隔的列表来定义多个泛型数据类型。

下面的实例定义了类 Stack<>,并实现了泛型方法来对元素进行入栈出栈操作:

实例

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
 
using namespace std;
 
template <class T>
class Stack {
private:
vector<T> elems; // 元素
 
public:
void push(T const&); // 入栈
void pop(); // 出栈
T top() const; // 返回栈顶元素
bool empty() const{ // 如果为空则返回真。
return elems.empty();
}
};
 
template <class T>
void Stack<T>::push (T const& elem)
{
// 追加传入元素的副本
elems.push_back(elem);
}
 
template <class T>
void Stack<T>::pop ()
{
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// 删除最后一个元素
elems.pop_back();
}
 
template <class T>
T Stack<T>::top () const
{
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// 返回最后一个元素的副本
return elems.back();
}
 
int main()
{
try {
Stack<int> intStack; // int 类型的栈
Stack<string> stringStack; // string 类型的栈
 
// 操作 int 类型的栈
intStack.push();
cout << intStack.top() <<endl;
 
// 操作 string 类型的栈
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -;
}
}
当上面的代码被编译和执行时,它会产生下列结果:
7
hello
Exception: Stack<>::pop(): empty stack
 

笔记列表

 
    1. gt

      gt@***ms.org

      第一个例子中typename改为class也是可以的:

      #include <iostream>
      #include <string> using namespace std; template <class T>
      inline T const& Max (T const& a, T const& b)
      {
      return a < b ? b:a;
      }
      int main ()
      { int i = 39;
      int j = 20;
      cout << "Max(i, j): " << Max(i, j) << endl; double f1 = 13.5;
      double f2 = 20.7;
      cout << "Max(f1, f2): " << Max(f1, f2) << endl; string s1 = "Hello";
      string s2 = "World";
      cout << "Max(s1, s2): " << Max(s1, s2) << endl; return 0;
      }
      gt

      gt

      gt@***ms.org

      8个月前 (05-02)

    2. gt

      gt@***ms.org

      C++ 中 typename 和 class 的区别

      在 C++ Template 中很多地方都用到了 typename 与 class 这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢?

      相信学习 C++ 的人对 class 这个关键字都非常明白,class 用于定义类,在模板引入 c++ 后,最初定义模板的方法为:

      template<class T>......

      这里 class 关键字表明T是一个类型,后来为了避免 class 在这两个地方的使用可能给人带来混淆,所以引入了 typename 这个关键字,它的作用同
      class 一样表明后面的符号为一个类型,这样在定义模板的时候就可以使用下面的方式了:

      template<typename
      T>......

      在模板定义语法中关键字 class 与 typename 的作用完全一样。

      typename 难道仅仅在模板定义中起作用吗?其实不是这样,typename 另外一个作用为:使用嵌套依赖类型(nested depended name),如下所示:

      class MyArray
      {
          public:
          typedef int LengthType;
      .....
      } template<class T>
      void MyMethod( T myarr )
      {
          typedef typename T::LengthType LengthType;
          LengthType length = myarr.GetLength;
      }

      这个时候 typename 的作用就是告诉 c++ 编译器,typename 后面的字符串为一个类型名称,而不是成员函数或者成员变量,这个时候如果前面没有
      typename,编译器没有任何办法知道 T::LengthType 是一个类型还是一个成员名称(静态数据成员或者静态函数),所以编译不能够通过。

#include<iostream>#include<vector>#include<cstdlib>#include<string>#include<stdexcept>usingnamespacestd;

template <classT>
classStack{private:
vector<T> elems; // 元素 public:
voidpush(Tconst&); // 入栈voidpop(); // 出栈Ttop()const; // 返回栈顶元素boolempty()const{// 如果为空则返回真。returnelems.empty();
}};

template <classT>
voidStack<T>::push(Tconst& elem){// 追加传入元素的副本elems.push_back(elem);
}template <classT>
voidStack<T>::pop(){if(elems.empty()){throwout_of_range("Stack<>::pop(): empty stack");
}// 删除最后一个元素elems.pop_back();
}template <classT>
TStack<T>::top()const{if(elems.empty()){throwout_of_range("Stack<>::top(): empty stack");
}// 返回最后一个元素的副本 returnelems.back();
}intmain(){try{Stack<int> intStack; // int 类型的栈 Stack<string> stringStack; // string 类型的栈 // 操作 int 类型的栈 intStack.push(7);
cout << intStack.top() <<endl;

// 操作 string 类型的栈 stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}catch(exceptionconst& ex){cerr << "Exception: " << ex.what() <<endl;
return -1;
}}

转:C++模板学习的更多相关文章

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

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

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. C++模板学习

    一.定义函数模板 template<class T> 函数定义 举个例子比较两个数大小: template<class T> int Compare(T a,T b) { ; ...

  4. C++模板学习随笔

    本文学习内容参考:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html C++模板 1.模板分为函数模板和类模板两种类型 函数模板针 ...

  5. 模板学习实践二 pointer

    c++ template学习记录 使用模板将实际类型的指针进行封装 当变量退出作用域 自动delete // 1111.cpp : 定义控制台应用程序的入口点. // #include "s ...

  6. 算法模板学习专栏之总览(会慢慢陆续更新ing)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/7495310.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  7. wordpress学习三:wordpress自带的模板学习

    在<学习二>里,大概说了下怎么去查找模板,本节我们以一个简单的模板为例子,继续说说wordpress的模板机制,看看做一个自己的模板需要哪些知识点. 页面模板渲染 wordpress的模板 ...

  8. C++模板学习笔记

    一个有趣的东西:实现一个函数print, 输入一个数组, 输出数组的各个维度长度. eg. ], b[][], c[][][]; print(a); //(2, 4) print(b); //(3, ...

  9. C++模板学习之优先队列实现

    转载:https://www.cnblogs.com/muzicangcang/p/10579250.html 今天将继续将强C++模板类的学习,同时为了巩固已经学习过的数据结构中有关优先队列的知识, ...

随机推荐

  1. scrollbar样式

    .friends-list-content { height: 520px; overflow-y: scroll; } .friends-list-content::-webkit-scrollba ...

  2. 解决SpringMVC put,patch,delete请求数据拿不到的问题

    解决SpringMVC put,patch,delete请求参数拿不到的问题 废话不多说,核心代码如下: 在web.xml中添加如下代码 <!-- 解决web端不能put,delete等请求的问 ...

  3. JAVA类与对象---实例变量与类变量的区别,实例方法和类方法的区别

    实例变量 实例变量声明在一个类中,但在方法.构造方法和语句块之外: 当一个对象被实例化之后,每个实例变量的值就跟着确定: 实例变量在对象创建的时候创建,在对象被销毁的时候销毁: 实例变量的值应该至少被 ...

  4. 多例模式,保证实例的唯一性,仅适用于form窗体

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  5. My deep learning reading list

    My deep learning reading list 主要是顺着Bengio的PAMI review的文章找出来的.包括几本综述文章,将近100篇论文,各位山头们的Presentation.全部 ...

  6. [php]require&require_once&include&include_once的用法与区别

    1.require和include是php引入php文件的两种方式,使用格式如下: require(include) 文件名; require(include) 变量(此变量存储的是文件名); 2.区 ...

  7. IO流-读取写入缓冲区

    例如FileReader和FileWriter在读取的时候是读一次或者写一次就请求磁盘,这样使用的时间非常的长,效率比较低,因此引入BufferedReader和BufferedWriter作为读取和 ...

  8. 二进制、十进制、十六进制(python)

    int(“x”,base=2/8/16)是把x都转换成十进制 二进制: 1111=1*2的3次方+1*2的2次方+1*2的1次方+1*2的0次方  =8+4+2+1=15 1000=1*2的3次方+0 ...

  9. 【zTree】zTree展开树节点

    今天在做zTree树的时候想着将第一级tree展开,于是利用下面方法: /** * 展开树节点的第一层 */ function openFirstTreenode(){ // 获取树对象 var tr ...

  10. http之100-continue

    [http之100-continue] 1.http 100-continue用于客户端在发送POST数据给服务器前,征询服务器情况,看服务器是否处理POST的数据,如果不处理,客户端则不上传POST ...