一、预设模板自变量的示例代码
你可以针对 class templates 定义其 template parameters 的默认值 , 这称为 default template arguments (预设模板自变量)。预设自变量值甚至可以引用前一步声明的 template parameters。例如在前面博客中提到的class Stack<> 中,你可以把「用来容纳元素」的容器类型定义为第二个template parameter,并使用std::vector<> 作为其默认值:
#include <vector>
#include <stdexcept>
template <typename T, typename CONT = std::vector<T> >
class Stack {
private:
CONT elems; // 元素
public:
void push(T const&); // push 元素
void pop(); // pop 元素
T top() const; // 传回 stack 的顶端元素
bool empty() const { // stack 是否为空
return elems.empty();
}
};
template <typename T, typename CONT>
void Stack<T,CONT>::push (T const& elem) {
elems.push_back(elem); // 追加元素
}
template <typename T, typename CONT>
void Stack<T,CONT>::pop() {
if (elems.empty()) {
throw std::out_of_range("Stack<>::pop(): empty stack");
}
elems.pop_back(); // 移除最后一个元素
}
template <typename T, typename CONT>
T Stack<T,CONT>::top() const {
if (elems.empty()) {
throw std::out_of_range("Stack<>::top(): empty stack");
}
return elems.back(); // 传回最后一个元素的拷贝
}
二、使用预设模板自变量
你可以像面对「单一template parameter」版本那样地使用这个新版stack。这时如果你只传递一个自变量表示元素类型,stack会使用预设的vector来管理其内部元素:
template <typename T, typename CONT = std::vector<T> >
class Stack {
private:
CONT elems; // 元素
...
};
当你在程序中声明一个Stack object时,也可以明确指定元素容器的类型:
#include <iostream>
#include <deque>
#include <cstdlib>
#include "stack3.hpp"
int main() {
try {
// stack of ints
Stack<int> intStack;
// stack of doubles,其内部使用 std::deque<> 来管理元素
Stack<double,std::deque<double> > dblStack;
//注:千万不要声明为 Stack<double, std::deque<int> >,
// 这是自己砸自己的脚,编译器无法为你做些什么。
// 操控 int stack
intStack.push(7);
std::cout << intStack.top() << std::endl;
intStack.pop();
// 操控 double stack
dblStack.push(42.42);
std::cout << dblStack.top() << std::endl;
dblStack.pop();
dblStack.pop();
} catch (std::exception const& ex) {
std::cerr << "Exception: " << ex.what() << std::endl;
return EXIT_FAILURE; // 以错误状态码离开程序
}
}
那么,只要像下面这样做:
Stack<double,std::deque<double> >
你就声明了一个 double stack,其内部以 std::deque<> 来管理元素。