C++类模板之双重模板参数(Template Template Parameters) 您所在的位置:网站首页 模板类作为函数参数怎么写 C++类模板之双重模板参数(Template Template Parameters)

C++类模板之双重模板参数(Template Template Parameters)

2024-07-17 11:12| 来源: 网络整理| 查看: 265

一个 模板参数 本身也可以是个 类模板。我们还是以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 实验室设备网 版权所有