F_G

许多问题需要说清楚就可以&&走永远比跑来的重要

导航

关于C++模板化

一、模板参数类型模板化

C++中的模板主要是函数模板和类模板。有些函数功能相同,但是数据类型不同,可也将其看做一类函数,可以使用函数模板来定义;有一些类所具有的函数成员的功能相同,但是仍然是数据类型不同,这是可以使用类模板对其进行定义。

我们可以从sort函数的第三个参数进一步理解。

sort(iter b,iter e,cmp)

这里的cmp可以是函数或者具有函数功能的类,即仿函数。比如我们定义升序排序。

template <typename T>
bool cmp(const T&a, const T&b){
    return a<b;
};

或者使用仿函数

template <Typename T>
struct cmp{
public:
    cmp();
    bool operator()(const T&a,const T&b){
        return a<b;
    }
};

若为降序排列,和上面非常类似。

二、系数参数化

关于参数的模板化,典型的是C++中的count_if函数

count_if(iter b,iter e,cmp);

template <Typename T>
struct cmp{
public:
    cmp(T num):num(num){}
    bool operator()(int i){
         return i>num;
    }
private:
    T num;
}

调用可以这样

count_if(iter b,iter e,cmp(12))

模板可以检测到是整数类型的cmp函数实现

三、方法参数化

比如一个求取特征的系统,现在要使用多种求特征的算法,来求取特征,由于特征太多,于是将其分发给多个人来完成,每个人负责一类算法,如何在将这些算法整合到系统之后,系统的整体的代码不需要修改?这时可以使用方法参数化。

我们可以首先定义一个ExtractBase class

#include <vector>
using namespace std;

class ExtractBase{
public:
    virtual vector<vector<double> > extract(vector<double> wav);
};

 所有特征提取方法都继承自这个基类。

例如:

#include <vector>
using namespace std;

class f1:public ExtractBase{
public:
    vector<vector<double> > extract(vector<double> wav);
};


class f2:public ExtractBase{
public:
    vector<vector<double> > extract(vector<double> wav);
};

对他们的调用,就简化了,因为他们有共同的特征提取方法,并且都有基类。

template <extractf Fun>
void extractAudio(vector<double> wav){
    Fun fun;
    vector<vector<double> > feature = fun.extractr(wav);
}


使用是这样的

extractAudio(v,f1)
extractAudio(v,f2)

这个方法不会关心是哪一种特征提取算法,因为他们都已经变成了模板,并且都有相同的特征提取接口。

有的同学,可能会有疑问,这里使用多态不就可以解决问题吗?有两个问题:

一、多态速度是问题

二、万一不能使用多态呢?????

 

四、参数模板简化

在模板的调用当中,我们有时发现一个问题,比如我们定义一个模板

template <class T,class t,class q>
.....

但是我们发现T是一个自定义的类,里面有t类型和q类型的数据成员,也就是说,t和q的类型是和T的类型紧密关联在一起的,这是如何简化这个问题,从而在使用的时候只需要指定T即可。
那么我们需要学会使用类型成员。我们一般都知道C++类的两种成员:数据成员和函数成员。但是类型成员常常被忽略掉。什么是类型成员呢?类型成员可以看做是对类型的进一步封装,经过封装,新的类型名字,成为了这个类的一个成员。比如:

class Example{
public:
    typedef int INT;
}

这时实际上INT是Example的一个类型成员。如何使用?

typename Example::INT a=12;

这时需要使用typename指定INT是这个类的一个类型成员不然会被误解为是一个数据成员。
有了这个知识点,这里的简化问题就好解决了。

假设T 类定义为如下:

 

posted on 2015-06-19 23:22  F_G  阅读(303)  评论(0编辑  收藏  举报