4. 模板中的非类型参数

在 函数模板 或 类模板 的类型参数声明列表(template<...>)中,类型参数列表中不但可以放置 typename 定义的类型参数,还可以方式 非类型参数,此类型参数通常是基础的数据类型。

template 的语法

template <typename 类型参数名1 [=默认类型1], 
          typename 类型参数名2 [=默认类型2],
          ...,
          基础数据类型 变量名1 [=默认值1],
          基础数据类型 变量名2 [=默认值2],
          ...>

例如上节我们定义的类模板 StaticArray 只能静态存储 100 个某种类型的数据,代码如下:

template <typename T=int>
class StaticArray {
    public:
        StaticArray() : data_cnt(0) {}
        void push_back(const T &value) { data[data_cnt] = value; data_cnt++; }
        int size() { return data_cnt; }
        T & operator[] (int index) { return data[index];}
    private:
        int data_cnt;
        T data[100];
};

现在我们在模版的 类型参数声明列表(template <typename T = int>)中 添加一个非类型参数 SIZE ,修改后的内容如下

template <typename T=int, int SIZE=100>

然后我们将静态数组的变量 data 的声明常数 100 改成 T data[SIZE];

这样我们就可以在使用 类模板 StaticArray 创建类时动态的改写 非类型参数 SIZE 的值来变化该类创建的对象保存数据的个数了。

示例

添加非类型参数的模板示例。

// filename: template3.cpp
#include <iostream>

using namespace std;

template <typename T=int, int SIZE=100>
class StaticArray {
    public:
        StaticArray() : data_cnt(0) {}
        void push_back(const T &value) { data[data_cnt] = value; data_cnt++; }
        int size() { return data_cnt; }
        T & operator[] (int index) { return data[index];}
    private:
        int data_cnt;
        T data[SIZE];
};

int main(int argc, char * argv[]) {
    // 创建存储 int 类型的静态数组 int_arr
    StaticArray<> int_arr; // 使用 T 的默认值int,SIZE默认为100
    // 创建存储 string 类型的静态数组 str_arr
    StaticArray<string, 3> str_arr;

    int_arr.push_back(11);
    int_arr.push_back(22);
    cout << "int_arr.size(): " << int_arr.size() << endl;
    cout << "int_arr[0]: " << int_arr[0] << endl;
    cout << "int_arr[1]: " << int_arr[1] << endl;

    str_arr.push_back("hello");
    str_arr.push_back("laowei");
    str_arr.push_back("weimingze");
    cout << "str_arr.size(): " << str_arr.size() << endl;
    cout << "str_arr[0]: " << str_arr[0] << endl;
    cout << "str_arr[1]: " << str_arr[1] << endl;
    cout << "str_arr[2]: " << str_arr[2] << endl;

    return 0;
}

编译也运行结果如下:

weimz@mzstudio:~$ g++ -o template3 template3.cpp
weimz@mzstudio:~$ ./template3 
int_arr.size(): 2
int_arr[0]: 11
int_arr[1]: 22
str_arr.size(): 3
str_arr[0]: hello
str_arr[1]: laowei
str_arr[2]: weimingze

练习

编写一个函数模板 MyMax 实现给定两个数字或者可以比较大小的数据类型,然后返回数值(也可以是其他的比较依据)较大的一个。并使用此函数模板进行数据的比较。