两种C++模板的使用

函数模板( Function templates)

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

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

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

在函数中使用模板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> 来确定传入参数
输出结果均已排好序。

在函数中使用模板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>

注:
最近在搬砖的时候发现了如下一种模板的用法,
template <typename BaseType = QGraphicsItem >

这句也可以在github qdraw项目里找到,最后在《c+=11primer》中找到了这种用法,原文是这么写的——

如果是一个类模板为其所有模板参数都提供了默认实参,且我们希望使用这些默认实参。
template <class T = int > //T默认为int

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器人梦想家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值