Skip to content

19.4 模板非类型参数

By Alex on June 19th, 2008 | last modified by Alex on January 23rd, 2020 | 翻译by dashjay 2020.07.10

在之前的课程中,我们已经了解如何使用模板来创建不受类型影响的函数和类。然而,模板类型参数并不是模板中唯一可用的参数。(However, template type parameters are not the only type of template parameters available.)。模板类型和函数可以利用另一类的模板参数,它们被叫做费类型参数(non-type parameter)。

非类型参数

一个模板非类型参数是一个特殊类型的参数不适合类型,却能被一个值替换。一个非类型参数可以为以下的其中一个。

  • 整形或枚举型的值
  • 指向类对象的指针或引用
  • 指向函数的指针或引用
  • 指向一个类函数的的指针或引用
  • std::nullptr_t

在下列的例子中,我们创建一个非类型(静态)数组类,同时使用一个类型参数和一个非类型参数。类型参数控制静态数组数据类型,非类型参数控制这个静态数组有多大。

#include <iostream>

// size is the non-type parameter
// size 是一个非类型参数
template <class T, int size>
class StaticArray
{
private:
    // The non-type parameter controls the size of the array
    // 非类型参数控制数组的大小
    T m_array[size];

public:
T* getArray();

    T& operator[](int index)
    {
        return m_array[index];
    }
};


// 展示一个带有非类型参数的模板类中的函数是如何在类外定义
// Showing how a function for a class with a non-type parameter is defined outside of the class
template <class T, int size>
T* StaticArray<T, size>::getArray()
{
    return m_array;
}

int main()
{
    // declare an integer array with room for 12 integers
    StaticArray<int, 12> intArray;

    // Fill it up in order, then print it backwards
    for (int count=0; count < 12; ++count)
        intArray[count] = count;

    for (int count=11; count >= 0; --count)
        std::cout << intArray[count] << " ";
    std::cout << '\n';

    // declare a double buffer with room for 4 doubles
    StaticArray<double, 4> doubleArray;

    for (int count=0; count < 4; ++count)
        doubleArray[count] = 4.4 + 0.1*count;

    for (int count=0; count < 4; ++count)
        std::cout << doubleArray[count] << ' ';

    return 0;
}

代码产生让以下结果:

11 10 9 8 7 6 5 4 3 2 1 0
4.4 4.5 4.6 4.7

一点值得注意的事情关于以上的例子,我们没有使用动态内存分配在 m_array 成员上!这是因为任何传入 StaticArray 类中的 size 实际上都是一个常数,例如如果你实例化了 StaticArray<int, 12>,那么编译器会使用 12 替换 size。因此 m_arrayint[12]类型的,这可以进行静态分配。

这个功能也被用在标准类 std::array 中,当你分配了一个 std::array<int, 5> 时,int是一个类型参数,5 是一个非类型参数。