C++类模板之双重模板参数(Template Template Parameters) | 您所在的位置:网站首页 › 模板类作为函数参数怎么写 › C++类模板之双重模板参数(Template Template Parameters) |
一个 模板参数 本身也可以是个 类模板。我们还是以Stack为例子 为了使用其它类型的元素容器,stack class 使用者必须两次指定元素类型:一次是元素类型本身, 另一次是容器类型 Stack vStack; // int stack,以 vector为容器如果使用 template template parameter,就可以只指明元素类型,无须再指定容器类型: Stack vStack; // int stack,以 vector为容器为了实现这种特性,我们必须把第二个 template parameter 声明为 template template parameter。 原 则上程序代码可以写为: // basics/stack7decl.cpp template 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(); } };与先前的 stack 差别在于,第二个 template parameter 被声明为一个 class template: template class CONT注意:CONT定义的是一个 class 类型,因此必须使用关键词 class来声明它。所以,下面代码是错误的 template //ERROR class Stack { 、、、 }类的成员函数也必须按此原则修改:必须指定其第二个template parameter为template template parameter。同样的规则也适用于成员函数的实作部份。例如成员函数 push()应该实作如下: template void Stack::push (T const& elem) { elems.push_back(elem); // 追加元素 }这就完成了吗?如果你试图使用上述新版 Stack,编译器会报告一个错误 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0999 类模板 "std::deque" 与 模板 template 参数 "CONT" 不兼容问题出在 template template argument 不但必须是个 template, 而且其参数必须严格匹配它所替换的 template template parameter 的参数。标准库中的 std::deque template 要求不只一个参数。第二参数是个配置器(allocator),它虽有默认值,但当它被用来匹配CONT 的参数时,其默认值会被编译器强行忽略了。 正确的代码如下所示 template class Stack { private: CONT elems; // 元素 ... }; 由于 ALLOC并未在程序代码中用到,或者你也可以把它省略掉。 template class Stack { private: CONT elems; // 元素 public: ... }最终的代码: #ifndef STACK_HPP #define STACK_HPP #include #include #include template 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(); } // 赋予一个「元素类型为 T2」的 stack template Stack& operator= (Stack const&); }; template void Stack::push(T const& elem) { elems.push_back(elem); // 追加元素 } template void Stack::pop() { if (elems.empty()) { throw std::out_of_range("Stack::pop(): empty stack"); } elems.pop_back(); // 移除最后一个元素 } template T Stack::top() const { if (elems.empty()) { throw std::out_of_range("Stack::top(): empty stack"); } return elems.back(); // 传回最后一个元素的拷贝 } template template Stack& Stack::operator= (Stack const& op2) { if ((void*)this == (void*)&op2) { // 是否赋值给自己 return *this; } Stack tmp(op2); // 创建 assigned stack的一份拷贝 elems.clear(); // 移除所有元素 while (!tmp.empty()) { // 复制所有元素 elems.push_front(tmp.top()); tmp.pop(); } return *this; } #endif // STACK_HPP使用 int main() { try { Stack intStack; // stack of ints Stack floatStack; // stack of floats // 操控 int stack intStack.push(42 ); intStack.push(7) ; // 操控 float stack floatStack.push(7.7); // 赋予一个「不同类型」的 stack floatStack = intStack; // 打印 float stack std::cout |
今日新闻 |
推荐新闻 |
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 |