C++泛型编程----(二)模板类

模板类也是模板,必须以关键字template开头,后接模板形参表。

template<class 形参1class 形参2,. . .class 形参n>
class 类名
{};


上面提到的模板参数和模板的模板参数在下一节Vector迭代器时再分析。
一、模板参数
(1)模板类型形参
类型形参由关键字class或typename后接说明符构成。在函数模板形参表中,二者含义相同。typename其实比class更直观,更清楚的指明后面的名字是一个类型名(包括内置类型),而class很容易让人联想到类声明或类定义。
此外,在使用嵌套依赖类型(nested depended name)时,必须用到typename关键字。

在类的内部可以定义类型成员。如果要在函数模板内部使用这样的类型,必须显示告诉编译器这个名字是一个类型,否则编译器无法得知它是一个类型还是一个值。默认情况下,编译器假定这样的名字指定(静态)数据成员,而不是类型。所以下面这段程序,如果去掉typename关键字,将会出现编译错误。

template <typename Parm, typename U>
Parm fcn(Parm *array, U value)
{
    typename Parm::size_type * p;
}

(2)非类型模板形参
模板形参也可以是非类型形参,在使用时非类型形参由常量表达式代替。

template <typename T, size_t N>
void array(T (&parm)[N])
{
    for (size_t i = 0; i != N; ++i)
        parm[i] = 0;
}
…
int x[42];
double y[10];
array(x); //  array(int (&)[42])
array(y); //  array(double (&)[10])

浮点数和类对象是不允许作为非类型模板参数的。

二、类模板的特化:
1、全特化:

//普通模板函数
template <class T>
struct Vector
{
public:
    Vector();
    Vector(const T* array, size_t size);
    ~Vector();
private:
    T* _start;
    T* _finish;
    T* _endOfStorage;
};

template <class T>
Vector<T>::Vector()
: _start(0)
, _finish(0)
, _endOfStorage(0)
{
    cout << "Vector<T>" << endl;
}

template <class T>
Vector<T>::Vector(const T* array, size_t size)
:_start(new T[size])
, _finish(_start)
, _endOfStorage(_start + size)
{
    cout << "Vector<T>" << endl;
}

template <class T>
Vector<T>::~Vector()
{
    if (_start)
        delete[] _start;
    _start = _finish = _endOfStorage = 0;
}
//特化成int 型
//特化后定义成员函数不再需要模板形参
template <>
struct Vector<int>
{
public:
    Vector();
    Vector(const int* array, size_t size);
    ~Vector();
private:
    int* _start;
    int* _finish;
    int* _endOfStorage;
};

Vector<int>::Vector()
: _start(0)
, _finish(0)
, _endOfStorage(0)
{
    cout << "Vector<int>" << endl;
}

Vector<int>::Vector(const int* array, size_t size)
:_start(new int[size])
, _finish(_start)
, _endOfStorage(_start + size)
{
    cout << "Vector<int>" << endl;
}

Vector<int>::~Vector()
{
    if (_start)
        delete[] _start;
    _start = _finish = _endOfStorage = 0;
}

2、偏特化:
偏特化可以分为两种
(1)部分参数的局部特化
(2)对模板参数进行更进一步的具体特化,比如特化为指针类型,或者引用类型
先来看第一种

///////////局部特化////////////////
//普通模板类
template <class T1,class T2>
class B
{
public:
    B();
private:
    T1 _b1;
    T2 _b2;
};
template <class T1, class T2>
B<T1, T2>::B()
{
    cout << "B<T1,T2>" << endl;
}

//局部特化第一个参数
template <class T2>
class B<int,T2>
{
public:
    B();
private:
    int _b1;
    T2 _b2;
};
template <class T2>
B<int, T2>::B()
{
    cout << "B<int,T2>" << endl;
}


下面是第二种偏特化:

template <class T1,class T2>
class B
{
public:
    B();
private:
    T1 _b1;
    T2 _b2;
};
template <class T1, class T2>
B<T1, T2>::B()
{
    cout << "B<T1,T2>" << endl;
}

//局部特化两个参数为指针类型
template <class T1, class T2>
class B<T1*, T2*>
{
public:
    B();
private:
    T1 _b1;
    T2 _b2;
    T1* _b3;
    T2* _b4;
};
template <class T1, class T2>
B<T1*, T2*>::B()
{
    cout << "B<T1*,T2*>" << endl;
}

三、模板的分离编译

总结:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值