曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3570|回复: 0
打印 上一主题 下一主题

[类模板]将模板用作参数

[复制链接]

716

主题

734

帖子

2946

积分

超级版主

Rank: 9Rank: 9Rank: 9

积分
2946
跳转到指定楼层
楼主
发表于 2013-12-17 10:46:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
模板可以包含类型参数(如 typename T) 和 非类型参数(如 int n)。模板还可以包含本身就是模板的参数,这种新增的特性,用于实现 STL 。

看下面的代码:

stacktp.h
[C++] 纯文本查看 复制代码
// stacktp.h -- a stack template
#ifndef STACKTP_H_
#define STACKTP_H_
template <class Type>
class Stack
{
private:
    enum {MAX = 10};    // 常量
    Type items[MAX];    // 栈
    int top;            // 栈顶
public:
    Stack();
    bool isempty();
    bool isfull();
    bool push(const Type & item); // 压栈
    bool pop(Type & item);        // 出栈
};

template <class Type>
Stack<Type>::Stack()
{
    top = 0;
}

template <class Type>
bool Stack<Type>::isempty()
{
    return top == 0;
}

template <class Type>
bool Stack<Type>::isfull()
{
    return top == MAX;
}

template <class Type>
bool Stack<Type>::push(const Type & item)
{
    if (top < MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}

template <class Type>
bool Stack<Type>::pop(Type & item)
{
    if (top > 0)
    {
        item = items[--top];
        return true;
    }
    else
        return false; 
}

#endif



temppram.cpp
[C++] 纯文本查看 复制代码
// tempparm.cpp – 模板作为参数
#include <iostream>
#include "stacktp.h"

template <template <typename T> class Thing>
class Crab
{
private:
    Thing<int> s1;
    Thing<double> s2;
public:
    Crab() {};
    // 假设 Thing 类有 push() 和 pop() 成员
    bool push(int a, double x) { return s1.push(a) && s2.push(x); }
    bool pop(int & a, double & x){ return s1.pop(a) && s2.pop(x); }
};
    
int main()
{
    using std::cout;
    using std::cin;
    using std::endl;
    Crab<Stack> nebula;
// Stack 必须匹配 template <typename T> class thing   
    int ni;
    double nb;
    cout << "Enter int double pairs, such as 4 3.5 (0 0 to end):\n";
    while (cin>> ni >> nb && ni > 0 && nb > 0)
    {
        if (!nebula.push(ni, nb))
            break;
    }
   
    while (nebula.pop(ni, nb))
           cout << ni << ", " << nb << endl;
    cout << "Done.\n";
    return 0; 
}



在 temppram.cpp 开头有下面的语句:
  1. template <template <typename T> class Thing>
  2. class Crab
复制代码
template <typename T> class Thing 是模板参数,其中 template <typename T> class 是类型,Thing 是参数。


假设有如下声明:
  1. Crab<King> legs;
复制代码
如果该声明要合法,那模板参数 King 就必须是一个模板类,并且其声明与模板参数 Thing 的声明匹配:
template <typename T>
class King { ... };

在 temppram.cpp 中还声明了两个对象:
Thing<int> s1;
Thing<double> s2;

那么对于上述的 legs 将用 King<int> 替换 Thing<int>,用 King<double> 替换 Thing<double> 。

然而,temppram.cpp 中包含了下面的声明:
  1. Crab<Stack> nebula;
复制代码
这样,Thing<int> 将被实例化为 Stack<int> ,而 Thing<double> 将被实例化为 Stack<double> 。总之,模板参数 Thing 将被替换为声明 Crab 对象时被用作模板参数的模板类型。

Crab 类的声明对 Thing 代表的模板类做了假设,即这个类包含一个 push() 方法,包含了一个 pop() 方法,且这些方法有特定的接口。Crab 类可以使用任何与 Thing 类型声明匹配,并包含方法 push() 和 pop() 的模板类。

还可以混合使用模板参数和常规参数。例如,Crab 类的声明还可以如下打头:
  1. template <template <typename T> class Thing, typename U, typename V>
  2. class Crab
  3. {
  4.     private:
  5.        Thing<U> s1;
  6.        Thing<V> s2;
  7.     ...
  8. };
复制代码
现在,成员 s1 和 s2 可以存储的数据类型为泛型,而不是用硬编码指定的类型。对于上述的 nebula 声明,可以修改成如下这样:
  1. Crab<Stack, int, double> nebula;  // T=Stack, U=int, V=double
复制代码
模板参数 T 表示一种模板类型,而类型参数 U 和 V 表示非模板类型。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-4-30 10:53 , Processed in 0.064698 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表