C++的泛型/通用编程:函数模板与类模板、模板函数的函数指针。template与class关键字区别。vector的类模板。


模板有什么用?

Template所代表的泛型编程是C++语言中的重要的组成部分。

实际上是建立一个通用函数,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据传入的实参来逆推出真正的类型。这个通用函数就称为函数模板(Function Template)。

函数模板并不缩短可执行程序,最终由编译器展开,最终的代码不包含任何模板,只含了为程序生成的实际函数。

STL中类似vector其实也是用模板类实现的。所以可以vectot vector
在这里插入图片描述

一、函数模板实例

template<typename  T,typename  T_2>
T calculate_temp(T cal_temp,T_2 cal_temp_2)
{
    cout <<"size of cal_temp = "<< sizeof(cal_temp)<<endl;
    cout <<"size of cal_temp_2 = "<< sizeof(cal_temp_2)<<endl;
    return cal_temp*cal_temp_2;
}

int main(int arg,char** argv)
{
    double  c=10.235;
    int a = 20;

    cout << calculate_temp(c,a)<<endl;


    return 0 ;
}

二、函数模板中class与typename 的区别?

下面展示一些 函数模板

template<class T>
T calculate_class(T cal_temp)
{
    cout <<"size of cal_temp = "<< sizeof(cal_temp)<<endl;
    return cal_temp*3;
}
template<typename  T>
T calculate_typename(T cal_temp)
{
    cout <<"size of cal_temp = "<< sizeof(cal_temp)<<endl;
    return cal_temp*3;
}

他们的调用方式如下:

int c = 10calculate_class(c);
calculate_typename<int>(c)

区别就是:typename 修饰的模板在编译时,需要明确指定参数类型。
但实际情况是不指明参数类型一样可以使用,原因是不同编译器有不同的实现方式。

关于typename,是C++98引入的,之前都是使用class。

如果不考虑对向后兼容的问题,应使用typename而不是class。

三、类模板

类模板与函数模板无差,
与函数模板不同的是,类模板在实例化时必须显式地指明数据类型,编译器不能根据给定的数据推演出数据类型。
类外定义成员函数。在类外定义成员函数时仍然需要带上模板头,类名后面也要带上类型参数。

#include <iostream>
using namespace std;
template<class T1, class T2>  //这里不能有分号
class Point{
public:
    Point(T1 x, T2 y): m_x(x), m_y(y){ }
public:
    T1 getX() const;  //获取x坐标
    void setX(T1 x);  //设置x坐标
    T2 getY() const;  //获取y坐标
    void setY(T2 y);  //设置y坐标
private:
    T1 m_x;  //x坐标
    T2 m_y;  //y坐标
};
template<class T1, class T2>  //模板头
T1 Point<T1, T2>::getX() const /*函数头*/ {
    return m_x;
}
template<class T1, class T2>
void Point<T1, T2>::setX(T1 x){
    m_x = x;
}
template<class T1, class T2>
T2 Point<T1, T2>::getY() const{
    return m_y;
}
template<class T1, class T2>
void Point<T1, T2>::setY(T2 y){
    m_y = y;
}
int main(){
    Point<int, int> p1(10, 20);
    cout<<"x="<<p1.getX()<<", y="<<p1.getY()<<endl;
    Point<int, char*> p2(10, "东经180度");
    cout<<"x="<<p2.getX()<<", y="<<p2.getY()<<endl;
    //除了对象变量,我们也可以使用对象指针的方式来实例化:
    Point<char*, char*> *p3 = new Point<char*, char*>("东经180度", "北纬210度");
    cout<<"x="<<p3->getX()<<", y="<<p3->getY()<<endl;
    return 0;
}

来自:http://c.biancheng.net/cpp/biancheng/view/2992.html

四、模板函数的指针

4.1 实例1:

模板函数insertionSort本身:

template<typename T>
void insertionSort(T arr[], int n){

  for( int i = 1 ; i < n ; i ++ ) {
      T e = arr[i];
      int j; // j保存元素e应该插入的位置
      for (j = i; j > 0 && arr[j-1] > e; j--)
          arr[j] = arr[j-1];
      arr[j] = e;
  }

  return;
}

参数列表中有函数指针的模板函数:

template<typename T>
void testSort(const string &sortName, void (*sort)(T[], int), T arr[], int n) {

    clock_t startTime = clock();
    sort(arr, n);
    clock_t endTime = clock();
    cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " s"<<endl;
}

模板函数insertionSort作为函数指针传参给testSort:


testSort("Insertion Sort", insertionSort,arr,n);

4.2 实例2:

下面这样是无法编译通过的。

template <class T> typedef void (*Action)(T) 

模板函数insertionSort本身:

template<typename T>
void insertionSort(T arr[], int n){

  for( int i = 1 ; i < n ; i ++ ) {
      T e = arr[i];
      int j; // j保存元素e应该插入的位置
      for (j = i; j > 0 && arr[j-1] > e; j--)
          arr[j] = arr[j-1];
      arr[j] = e;
  }

  return;
}

参数列表中有函数指针的模板函数:

template<typename T>
	struct Type
	{
		typedef void(*aaaaa)(T[], int);
	};
void testSort(const string &sortName, Type<int>::aaaaa sort, int arr[], int n) {

	clock_t startTime = clock();
	sort(arr, n);
	clock_t endTime = clock();

	cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;

}

模板函数insertionSort作为函数指针传参给testSort:


testSort("Insertion Sort", insertionSort,arr,n);

参考

https://blog.csdn.net/u010632547/article/details/105634066

https://www.cnblogs.com/easyfrog/archive/2012/11/04/2753468.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值