Nontype Class Template Parameters(非类型类模板参数)
来源:互联网 发布:网络电视剧生死征途 编辑:程序博客网 时间:2024/06/05 05:24
一、需求引入
上一篇博客实作了一个「元素个数可变」的stack class。与之对比,你也可以实作另一种stack,透过一个固定大小(fixed-size)的 array来容纳元素。这样做的好处是不必考虑诸如内存管理之类的问题。然而array大小的决定是一件比较困难的事:array愈小则stack愈容易满溢,array愈大则愈容易造成空间浪费 。 一个可行的解决办法是让使用者指定array大小 , 这个大小也就是stack 的最大元素个数。
二、代码示例
为了完成以上想法,我们应该把大小值当作一个 template parameter:
#include <stdexcept>
template <typename T, int MAXSIZE>
class Stack {
private:
// 元素
T elems[MAXSIZE];
// 当前的元素个数
int numElems;
public:
// 构造函数
Stack();
// push 元素
void push(T const&);
// pop 元素
void pop();
// 传回 stack 顶端元素
T top() const;
// stack 是否为空
bool empty() const {
return numElems == 0;
}
// stack 是否已满
bool full() const {
return numElems == MAXSIZE;
}
};
// 构造函数
// 一开始并无任何元素
template <typename T, int MAXSIZE>
Stack<T,MAXSIZE>::Stack () : numElems(0) {
// 不做任何事
}
template <typename T, int MAXSIZE>
void Stack<T,MAXSIZE>::push (T const& elem) {
if (numElems == MAXSIZE) {
throw std::out_of_range("Stack<>::push(): stack is full.");
}
// 追加
elems[numElems] = elem;
// 元素总数加 1
++numElems;
}
template <typename T, int MAXSIZE>
void Stack<T,MAXSIZE>::pop () {
if (numElems <= 0) {
throw std::out_of_range("Stack<>::pop(): empty stack.");
}
// 元素总数减 1
--numElems;
}
template <typename T, int MAXSIZE>
T Stack<T,MAXSIZE>::top () const {
if (numElems <= 0) {
throw std::out_of_range("Stack<>::top(): empty stack.");
}
// 传回最后一个元素
return elems[numElems - 1];
}
三、使用
使用上述 class template 时,必须同时指定 (1) 元素类型和 (2) stack 元素的最大数量:
#include <iostream>
#include <string>
#include <cstdlib>
#include "stack4.hpp"
int main() {
try {
// 最多容纳 20 个 int 元素
Stack<int,20> int20Stack;
// 最多容纳 40 个 int 元素
Stack<int,40> int40Stack;
// 最多容纳 40 个 string 元素
Stack<std::string,40> stringStack;
// 操控「最多容纳 20 个 int 元素」的那个 stack
int20Stack.push(7);
std::cout << int20Stack.top() << std::endl;
int20Stack.pop();
// 操控「最多容纳 40 个 string 元素」的那个 stack
stringStack.push("hello"); 32
std::cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
} catch (std::exception const& ex) {
std::cerr << "Exception: " << ex.what() << std::endl;
return EXIT_FAILURE; // 传回一个错误状态码
}
}
注意,每一个被实例化(instantiated) 的 class template 都有各自的类型。 (注:常见的误会是:上述三个 stacks 隶属同一类型。这是错误观念。)因此 int20Stack 和 int40Stack 是两个不同类型,不能互相进行隐式或显式转换,两者不能换用(彼此取代),也不能互相赋值。
你可以指定 non-type template parameters 的默认值:
template <typename T = int, int MAXSIZE = 100>
class Stack {
...
};
然而从设计角度来看,这样做并不恰当。Template parameters 的默认值应该符合大多数情况下的 要求, 然而把 int 当做预设元素类型, 或指定 stack 最多有 100 个元素, 并不符合一个 「通用型 stack」 的需求。 更好的作法是让使用者指定这两个参数的值, 并在文件中说明它们的意义
- Nontype Class Template Parameters(非类型类模板参数)
- c++ template笔记(3)非类型模板参数nontype template parameters
- C++ - 非类型模板参数(nontype template parameters) 使用 及 代码
- C++ - 非类型模板参数(nontype template parameters) 使用 及 代码
- Nontype template parameters(非型别模板参数)
- Template Template Parameters(双重模板参数)
- 非类型模板类参数
- 模板非类型参数
- 非类型模板参数
- 非类型模板参数
- 非类型模板参数
- 非类型模板参数
- 非类型模板参数
- [c++ template]非类型的函数模板以及非类型的类的模板
- 模板类中的表达式(非类型)参数
- template non-type parameter 非类型参数
- 非类型模板参数与 非类型类模板参数的使用
- 非类型的模板参数
- 新年彩蛋:Spring Boot自定义Banner
- Android系统服务之WindowManager整理
- 使用Node.js+Socket.IO搭建WebSocket
- 名企笔试:百度2015校招笔试题(头巾问题)
- Burpsuite - Extension: SQLipy
- Nontype Class Template Parameters(非类型类模板参数)
- tomcat各目录(文件)作用
- hibernate使用c3p0连接池
- 在CentOS7中安装Oracle 11g
- (学习总结)鸟哥基础篇第三版:第十五章
- 我用时间称自己的重量,然后数落自己的肤浅与狂妄--2016年终总结
- Tomcat连接池报错:DBCP object created by the following code was never closed
- 理解 RxJava 线程模型
- DBUtils User's Guide及中文