STL基础(三)模板特化补充

1、基模板

基模板指的是一个泛型模板定义,它为特化模板提供了基础,基模板可以有完整实现,也可以没有完整实现。

我们比较熟悉有完整实现的基模板,编译器编译时会替换掉模板参数,生成完整的函数或者类。

如果一个模板没有完整实现,那么我们使用它之前,必须要先实现它的特化版本。

// mytemplate.h
template <typename T>
class TestClass;

// main.cpp
template<>
class TestClass<int> {
public:
    void print() {
        std::cout << "int template" << std::endl;
    }
};

int main() {
    TestClass<int> tc;
    tc.print();
    // TestClass<double> tc2;   // error:不允许使用不完整的类型
}

可以看到,虽然基模板template <typename T> class TestClass没有完整实现但是我们依旧可以正常使用,这是因为cpp文件实现了int特化版本。如果我们创建double类型实例TestClass<double> tc2则会报出不允许使用不完整的类型的error。

由于基模板为特化模板提供了基础,所以如果上例中没有基模板,那么编译器将会提示TestClass不是模板。

2、特化的实现位置

在简单模板一章的最后有一段说明 “模板类的方法实现必须要放在头文件当中”,这句话需要加一个限定词基模板

上面的例子中可以看到模板定义在.h文件中,但是特化模板却实现在cpp文件中。

如果特化版本和基模板实现在一个文件中,说明实现的特化版本可以供所有编译单元使用;如果特化版本实现在某个cpp文件中,说明这个特化模板仅供当前编译单元使用。

3、偏特化

之前我们看到的偏特化都是以下形式,将模板的某个参数特化为具体类型:

template <typename T1, typename T2>
class TestClass2;

template <typename T1>
class TestClass2<T1, int> {
};

但是还有一种特化形式:

template <typename T1, typename T2>
class TestClass2;

template <typename T1>
class TestClass2<T1*, int&> {
};

T*int&表明了当前特化版本适用的具体类型或类型模式,只有当第一个模板参数是T*类型(指针类型),第二个模板参数是int&(int引用)的情况下才会使用这个特化模板。

举一个具体的例子:

template <typename T1, typename T2>
class TestClass2 {
public:
    void print() { std::cout << "template default" << std::endl; }
};

template <typename T1, typename T2>
class TestClass2<T1*, T2> {
public:
    void print() { std::cout << "template specialization" << std::endl; }
};

int main() {
    TestClass2<int, int> tc;
    tc.print();     // template default
    TestClass2<int*, int> tc2;
    tc2.print();    // template specialization
}

模板特化可以要求模板参数为任何类型,常用的包括:

  • 基本类型:如intdouble等;
  • 指针类型:T*及带修饰的const T*等;
  • 引用类型:T&及带修饰的const T&等;
  • 自定义类型:
  • 数组类型:如int[];
  • 函数指针类型:如void (*)();
  • 函数类型:如void(),这一点暂时不去深入研究;

模板特化可以帮助我们提取类型的修饰,例如指针、引用、const、数组等等,这将在STL中有很大的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山渺渺

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值