In previous lessons, you’ve learned how to use template type parameters to create functions and classes that are type independent. However, template type parameters are not the only type of template parameters available. Template classes and functions can make use of another kind of template parameter known as a non-type parameter.
在前面的课程中,你已经学习怎么使用模板类型参数来创建独立于特定类型的函数和类。然而模板类型参数并不是模板参数的唯一参数,模板类和模板函数可以有其他的模板参数,叫做非模板参数。
A template non-type parameter is a special type of parameter that does not substitute for a type, but is instead replaced by a value. A non-type parameter can be any of the following:
一个模板的非类型参数是一种特别的类型参数,并不作为类型的替代,而是作为一个值。一个非类型参数可以是以下的任何东西:
-
A value that has an integral type or enumeration
一个int类型的值或者是枚举类型的值
-
A pointer or reference to a class object
一个指向类对象的指针或者引用
-
A pointer or reference to a function
一个函数指针或者函数引用。
-
A pointer or reference to a class member function
一个指向成员函数的一个指针或者引用
-
std::nullptr_t
空指针类型
In the following example, we create a non-dynamic (static) array class that uses both a type parameter and a non-type parameter. The type parameter controls the data type of the static array, and the non-type parameter controls how large the static array is.
在下面的例子中,我们创建一个非动态数组模板类,使用了类型参数和非类型参数。类型参数控制静态数组的类型,非类型的参数控制静态数组的大小
#include <iostream>
template <class T, int size> // size is the non-type parameter
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;
}
This code produces the following:
11 10 9 8 7 6 5 4 3 2 1 0
4.4 4.5 4.6 4.7
One noteworthy thing about the above example is that we do not have to dynamically allocate the m_array member variable! This is because for any given instance of the StaticArray class, size is actually constant. For example, if you instantiate a StaticArray<int, 12>, the compiler replaces size with 12. Thus m_array is of type int[12], which can be allocated statically.
值得注意的事情是,我们没有动态分配内存,这是因为对于任意给订的StaticArray的实例,size都是一个常量。举个例子,如果你实例化一个StaticArray<int, 12>, 编译器会把size替换成12这个值,所以就分配了静态空间。
This functionality is used by the standard library class std::array. When you allocate a std::array<int, 5>, the int is a type parameter, and the 5 is a non-type parameter!
这个非类型参数的特性就被标准库中的std::array用了。当你分配这个的时候std::array<int, 5>,int是类型参数,5是一个非类型参数。