《C++ Primer plus》中的模板

函数模板

  •  函数模板
template <typename T>
void Swap(T &a, T &b); // 函数模板原型

template <typename T>
void Swap(T &a, T &b) // 函数模板定义
{
    T temp;
    temp = a;
    a = b;
    b = temp;          
}

其中,temlate和typename为关键字,typename也可用class替代,T为类型名,也可以是任何遵守C++命名规则的名称,但常用T这一简单的名称。

模板多放在头文件中,并在需要使用模板的文件中包含头文件。

  • 重载的模板

可以想重载常规函数定义那样重载模板定义。和常规重载一样,被重载的模板的函数特征标必须不同。

值得注意的一点是,并非所有的模板参数都必须是模板参数类型。

  • 显式具体化

对于给定的函数名,可以有非模板函数,模板函数和显式具体化模板函数及它们的重载版本。显式具体化(explicit specialization)的原型和定义应以template <>开头,并通过名称来指出类型。显式具体化优先于常规模板,而非模板函数优先与具体化和常规模板。

template <> void Swap<job>(job &, job &); // 函数模板显式具体化原型

template <> void Swap<job>(job &, job &) // 函数模板显式具体化定义
{
    ...;
}

其中,<job>可省略。

  • 实例化

在代码中包含函数模板本身,并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用模板为特定类型生成函数定义时,得到的是模板实例(instantiation),这种实例化方式被称为隐式实例化(implicit instantiation)。而显式实例化(explicit instantiation)可以直接命令编译器创建特定的实例,其语法为用<>符号指示类型并在声明前加上关键字template:

template void Swap<int>(int, int); // 函数模板显式实例化

显式实例化让编译器使用Swap()模板生成int类型的函数定义,而显示具体化让编译器不要使用Swap()模板来生成函数定义,而使用专门为某类型显式定义的函数定义。显式具体化声明在关键字template后包含<>,而显示式实例化没有。

在同一个文件中使用同一种类型的显式实例化和显式具体化将会出错。

隐式实例化、显式实例化和显式具体化统称为具体化。它们的相同之处在于,他们表示的都是使用具体类型的函数定义,而非通用描述。

...
template <typename T>
void Swap(T &, T &); // 模板原型

template <> void Swapp<job>(job &,  job &); // 显式具体化,编译器不使用模板生成函数定义
int main()
{
    template void Swap<char>(char &, char &); // 显式实例化,编译器使用模板生成函数定义

    short a, b;
    ...
    Swap(a, b); // 隐式实例化

    job n, m;
    ...
    Swap(n, m); // 使用显式具体化

    char g, h;
    ...
    Swap(g, h); // 使用显式实例化  
}

类模板

p567

posted @ 2021-08-15 15:32  溪嘉嘉  阅读(59)  评论(0编辑  收藏  举报