第四章:模板进阶

作者 : admin 本文共1383个字,预计阅读时间需要4分钟 发布时间: 2024-06-9 共2人阅读

目录

一、非类型模板参数:

1.1定义:

1.2用途:

1.3举例:

二、模板特化:

2.1概念:

2.2实例解析——全特化:

2.3实例解析——偏特化:

2.4对某种类型特化:

三、模板的分离编译:

3.1模板分离编译会造成的问题:

3.2解决分离编译问题——显式实例化:

3.3将模板声明和定义分离,但是都写在一个头文件中。


一、非类型模板参数:

1.1定义:

  • C++中,除了普通的类型参数外,模板还可以接受非类型参数(Non-type Parameter)。非类型参数是指模板参数中的一个特殊种类,它不是类型,而是一个常量表达式,可以是整数、枚举、指针等。

1.2用途:

  • 数组大小:可以在编译时确定数组的大小。
  • 枚举值:可以在编译时确定枚举的值。
  • 容器容量:可以在编译时确定容器的容量。
  • 模板元编程:用于实现模板元编程技术,例如计算阶乘、斐波那契数列等。

1.3举例:

  • 如果要初始化一个1000大小和10大小的栈。
template 
class Stack 
{
    ...
}


Stack s1;
Stack s2;

二、模板特化:

2.1概念:

  • 模板特化(Template specialization)是C++中模板的一种特性,它允许为模板参数的特定值或特定类型提供定制化的实现。
  • 全特化(Full specialization):为模板的所有参数提供特定的实现。
  • 偏特化(Partial specialization):只为模板的一部分参数提供特定的实现。

2.2实例解析——全特化:

  • 有一个类有两个模板参数T1和T2。
template
class test
{
public:
    test()
    {
        cout<<"test"<<endl;
    }
private:
    T1 _n1;
    T2 _n2;
}
  • 如果要特殊处理T1为int,T2为double的情况,就可以将模板特化为:
template
class test
{
    ...
}
  • 需要注意的是一定要在开头写template

2.3实例解析——偏特化:

  • 一部分模板参数被特化。
template
class test
{
    ...
}
  • 先匹配全特化,如果没有再匹配偏特化,最后才匹配无特化的模板。

2.4对某种类型特化:

  • 处理模板实参为指针的情况。
template
class test
{
    ...
}
  • 如果传来实例化的实参为指针类型,就走这个特化。

三、模板的分离编译:

3.1模板分离编译会造成的问题:

  • 在C++中,模板实例化的过程主要发生在编译阶段,而不是链接阶段。当链接时,由于没有实例化模板为具体的类,就不会在符号表生成对应的符号。
  • 链接器在链接阶段会找不到相应的符号,导致未定义符号错误。

3.2解决分离编译问题——显式实例化:

  • 在源文件中明确地实例化可能需要的模板类型。
  • 比如对函数模板ADD,分别显式实例化他的int和double版本。
  • 实例化不够灵活,需要手动实例化可能的类型。
  • 可能导致代码膨胀,多个源文件可能在不知情的情况下,对一个类型实例化多份模板。
实例化一份int
template
int ADD (const int& left,const int& right)

实例化一份double
template
double ADD (const double& left,const double& right)

3.3将模板声明和定义分离,但是都写在一个头文件中。

  • 最常见且直接的方法是将模板的声明和定义都放在头文件中。这确保了每个使用模板的翻译单元都能看到完整的模板定义,并能够生成所需的实例化代码。

 

本站无任何商业行为
个人在线分享 » 第四章:模板进阶
E-->