前面已经介绍了函数模板和类模板,还介绍了类模板的默认参数,在代码示例中都是用具体类型来作为模板参数的。
实际上,模板参数不局限于类型,普通值也可以作为模板参数,也就是本篇要讲的内容:非类型模板参数。
非类型模板参数
非类型模板参数的使用和类型模板参数有些不一样,不需要 typename
关键字了,直接指定具体类型。
如下代码所示:
1template<typename T, int MAXSIZE = 20>
2class STACK {
3private:
4 T elems[MAXSIZE];
5 int numElems;
6
7public:
8 STACK();
9
10 void push(T const &);
11 void pop();
12 T top() const;
13 bool empty() const {
14 return numElems == 0;
15 }
16
17 bool full() const {
18 return numElems == MAXSIZE;
19 }
20};
21
22template<typename T, int MAXSIZE>
23STACK<T, MAXSIZE>::STACK() :numElems(0) {
24
25}
26
27template<typename T, int MAXSIZE>
28void STACK<T, MAXSIZE>::push(const T &elem) {
29 if (numElems == MAXSIZE) {
30 throw std::out_of_range("Stack<>::push(): stack is full");
31 }
32 elems[numElems] = elem;
33 numElems++;
34}
35
36template<typename T, int MAXSIZE>
37void STACK<T, MAXSIZE>::pop() {
38 if (numElems <= 0) {
39 throw std::out_of_range("Stack<>::pop(): empty stack");
40 }
41 numElems--;
42}
43
44template<typename T, int MAXSIZE>
45T STACK<T, MAXSIZE>::top() const {
46 if (numElems <= 0) {
47 throw std::out_of_range("Stack<>::top(): empty stack");
48 }
49 return elems[numElems - 1];
50}
51
52int main() {
53 STACK<int> intStack;
54 intStack.push(1);
55 intStack.top();
56 intStack.pop();
57
58 STACK<int,10> int10Stack;
59 int10Stack.push(1);
60 int10Stack.top();
61 int10Stack.pop();
62 return 0;
63}
在使用非类型模板参数的时候,也就是基于值的模板参数,要么显示地指定这些值,要么作为默认参数有默认值。
非类型的函数模板参数
除了上面的类模板,函数模板同样可以用非类型的模板参数。
1template <typename T,int VAL = 3 >
2T addValue(T const&x){
3 return x + VAL;
4}
5
6int main{
7 addValue(10);
8 return 0;
9}
可以看到函数模板同样是可以用默认参数值的。
非类型模板参数的限制
不是所有的类型都可以作为非类型模板参数,它是有限制的。
通常而言,只有常整数(包括枚举值)或者指向外包链接对象的指针 才可以,而浮点数和类对象是不允许作为非类型模板参数的。
1template<double VAT>
2double process(double v){
3 return v * VAT;
4}
以上的代码示例就是不行的。
小结
非类型模板参数只是 C++ 模板知识点里面一个小方面了,但在某些场景还在能发挥大作用的。
原创文章,转载请注明来源: C++ 模板系列小结02-非类型模板参数
相关文章
- C++ 模板系列小结01-函数模板和类模板
- C++ 标准容器库小结
- 从零打造渲染引擎系列01-什么是渲染引擎
- iOS开发 - 在 Swift 中去调用 C/C++ 代码
- 2021 技术新番 - 从零打造渲染引擎系列
留言