C++学习 - 泛型编程基础

时间:2022-01-05 01:40:27

C++作为兼容C语言却又更强大的语言来说,C++真正强大且区别于C的地方就是泛型编程了。

在C++中,模板是泛型编程的基础,模板是创建类和函数的蓝图。

模板定义

假设要写一个函数比较两个值,指出第一个值是小于、等于还是大于第二个值。我们可以用函数重载:

int compare( const int &a, const int &b){
if(a == b){
return 0;
}
return a>b?1:-1;
}

int compare( const double &a, const double &b){
if(a == b){
return 0;
}
return a>b?1:-1;
}

这两个函数基本相同,唯一不同的是参数,但是这种太麻烦了,也容易出错,并且有时候根本不知道比较的到底是哪个类型。

定义函数模板

定义一个函数模板,就是一个独立类型的函数。如下:

template < typename T >
int compare( T &a, T &b ){
if( a == b ){
return 0;
}
return a>b?1:-1;
}

模板的定义以关键字template开始,后面接模板参数( template parameter list ),模板形参表是用尖括号括起来的一个或多个模板形参( template parameter ),形参之间用逗号分割。

使用函数模板

使用函数模板时,编译器推断是哪个模板实参( template argument )绑定到模板形参。一旦编译器确定了实际的模板实参,就称他实例化( instantiate )了一函数模板的实例。

int main(){
cout << compare(0, 1) <<endl;
cout << compare("abc", "bcd") <<endl;
return 0;
}

编译器把实例化compare的两个不同版本,编译器用Int代替T 创建第一个,用string替换T创建第二个。

inline函数模板

函数模板可以用与非模板函数一样的方式声明为inline。说明符放在模板形参表之后、返回类型之前,不能放在关键字template之前。

template < typename T > inline T min(const T&, const T&);

定义类模版

我们定义类模版的时候同函数模板一样。
例如我们定义一个Point类,可能是2d(x和y)的,可能是3d(x,y和z)的,所以需要类模版。第一种是定义3d的Point:

template < class type >
class Point3d
{
public:
Point3d( type x = 0.0, type y = 0.0, type z = 0.0)
: _x(x), _y(y), _z(z) {}

type x(){
return _x;
}

void x( type xval ){
_x = xval;
}

private:
type _x;
type _y;
type _z;
};

或者我们把参数个数也变成可变的:

template < class type, int dim >
class Point{

public:
Point();
Point(type coords[dim]){
for (int index = 0; index < dim; index++) {
_coords[index] = coords[index];
}
}

type& operator[] (int index){
assert(index < dim && index >= 0);
return _coords[index];
}

type operator[] ( int index ) const{
assert(index < dim && index >= 0);
return _coords[index];
}

private:
type _coords[dim];
};

这样就可以了。使用的时候直接声明就可以了。

Point< int, 3 > point;

以上就是泛型编程的基础了。