C++模板中的函数式参数

前面我们提到过,模板类至少有一个类参数,但是可以有多个参数,这些参数中可以存在非类类型的参数,例如系统内建的普通数据类型参数或程序自定义的数据类型参数,我们将这种非类类型的参数称之为函数式参数

【例 1】
template< class T, int S, double R>
class test
{
    //......
};
在本例中例举了函数式参数的用法,在模板头中,先是一个类参数 T,之后是两个函数式参数 S 和 R。

【例 2】
#include <iostream>
using namespace std;

template< class T , int S>
class array
{
public:
    array();
    T & operator[]( int );
    const T & operator[] ( int )const;
    int getlen()const{ return length; }
    ~array();
private:
    int length;
    T * num;
};

template< class T , int S>
array<T, S>::array()
{
    num = new T[S];
    length = S;
}

template< class T , int S>
array<T, S>::~array()
{
    delete[] num;
}

template< class T , int S>
T & array< T, S > ::operator[] (int i)
{
    if( i < 0 || i >= length)
        throw string( "out of bounds" );
    return num[i];
}

template< class T , int S>
const T & array< T, S > ::operator[] ( int i ) const
{
    if( i < 0 || i >= length)
        throw string( "out of bounds" );
    return num[i];
}

template< class T , int S>
ostream & operator<<( ostream & out, const array <T, S> & A)
{
    for(int i=0; i < A.getlen(); i++)
        out<< A[i] << " ";
    return out;
}

int main()
{
    array< int, 10> A;
    for(int i = 0; i < 10; i++)
    {
        A[i] = 2*i;       
    }
    cout<< A << endl;
    return 0;
}
在本例中,我们将前面的 array 模板类进行了修改,使之有两个参数,一个是类参数 T,另一个是函数式参数 S。修改后的 array 模板类用默认构造函数替代了带参构造函数。因为在模板类中添加了一个函数式参数 S 以表示数组的大小,因此定义对象时无需再利用带参构造函数的参数来确定数组的大小。

对于前面章节中创建的 array 模板类,我们需要以如下的方式定义对象:
array<int> A(100);
array<string> S(10);
修改后的 array,我们只需要按照如下方式定义对象:
array<int, 100> A;
array<string, 10> S;
修改后的 array 类的类名变为了array<T, S>。对于修改后的 array 类,想要将其实例化则必须提供两个参数的实例,例如:
array<int, 100> A;
array<double, 10> D;
都是可以正确实例化并定义对象的,但是如果只提供一个参数则是不可以的,例如:
array<int> A;
array<10> D;
这两种情况都是错误的的实例化。

在模板类实例化过程中,我们需要用具体的数据类型来代替类参数,用具体的数值来替换函数式参数,如此才能实例化成功。