两步学会C++模板的使用<1>

来源:互联网 发布:sublime js高亮插件 编辑:程序博客网 时间:2024/05/17 06:33

函数模板( Function templates)

模板(Templates)使得我们可以生成通用的函数,这些函数能够接受任意数据类型的参数,可返回任意类型的值,而不需要对所有可能的数据类型进行函数重载。这在一定程度上实现了宏(macro)的作用。它们的原型定义可以是下面两种中的任何一个:

template <typename identifier> function_declaration;template <class identifier> function_declaration;

上面两种原型定义的不同之处在关键字class 或 typename的使用。它们实际是完全等价的,因为两种表达的意思和执行都一模一样。

  1. 在函数中使用模板typename
#include "stdafx.h"#include <iostream>#include <vector>#include <string>#include <algorithm>template <typename Tx>  //这一句的作用就是定义Tx参数类型,根据传入的数据类型确定void insertsort(vector<Tx> &numbers){//插入排序      int numlen=numbers.size();      int flag;      Tx temp;      for (int i=1;i<numlen;i++){            temp=numbers[i];            for (flag=i;flag>0&&numbers[flag-1] > temp;flag--)                 numbers[flag]=numbers[flag-1];            numbers[flag] = temp;      }}int _tmain(int argc, _TCHAR* argv[]){      int a[]={9,8,7,6,5,4,3,2,1};      char b[]={'j','f','e','d','c','b','a'};      vector<int> numbers(a,a+9);      vector<char> character(b,b+7);      insertsort(numbers);      insertsort(character);      for (int i=0;i<character.size();i++)            cout<<character[i]<<" ";      cout<<endl;      system("pause");}

函数模板运行结果

以上代码为插入排序的函数实现,输入有两种格式一种是int型,一种为char型。通过template < typename Tx> 来确定传入参数
输出结果均已排好序。
2. 在函数中使用模板class

#include "stdafx.h"#include <iostream>template <class Ty> Ty getMin (Ty a, Ty b) {    Ty res;    res = a<b ? a : b;    return res;}int _tmain(int argc, _TCHAR* argv[]){      int a[2]={123,321};      char b[2]={'g','p'};      int numMin=getMin(a[0],a[1]);//传入为int      char charMin=getMin(b[0],b[1]);//传入为char      cout<<numMin<<endl<<charMin<<endl;      system("pause");}

在这个样例中,a、b、res都为Ty型, 即在class模板声明时在class 后边所接的Ty参数
3. 在类中使用模板
我们也可以定义类模板(class templates),使得一个类可以有基于通用类型的成员,而不需要在类生成的时候定义具体的数据类型,例如:

//test.h#include <iostream>#include <vector>#include <string>template <class Tz>class Stacks{private:      std::vector<Tz> elems;public:      void push_e(Tz const &in);      void pop_e();      Tz top_e();      bool empty_e() const{            return elems.empty();      }};template <class Tz>void Stacks<Tz>::push_e(Tz const &in){      elems.push_back(in);}template <class Tz>void Stacks<Tz>::pop_e(){      if (elems.empty()) throw out_of_range("Stack<>::pop(): empty stack");      elems.pop_back();}template <class Tz>Tz Stacks<Tz>::top_e(){      if (elems.empty()) throw out_of_range("Stack<>::pop(): empty stack");      return elems.back();}
//test.cpp#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){      Stacks<std::string> string_elems;     Stacks<int> int_elems;     string_elems.push_e("Hello world");     int_elems.push_e(1001);     int_elems.push_e(1002);     cout<<int_elems.top_e()<<endl;     int_elems.pop_e();     cout<<int_elems.top_e()<<endl<<string_elems.top_e()<<endl;     system("pause");}

运行结果如下:
类模板运行结果
在上述类模板的使用中定义了class Stacks,类型为template <class Tz>
使用STL vector作为容器,存入不同类型的数据。
这个类实现了以下几个功能 pop(弹出最后一个元素)、push(在最后插入一个元素)、Isempty(判断容器是否为空)、top(返回最后一个元素)
如下是笔者在编写该段程序时遇到需要注意的点 :

  • void Stacks<Tz>::pop_e()在写函数的定义时必须要在类的后边加上< Tz >模板参数,否则编译无法通过
  • 每个函数的定义前都需要加 template <class Tz>
原创粉丝点击