• c++中函数模板/未完待续


    函数模板是通用的函数描述,它们使用范型来定义函数,其中的范型可用具体的类型(如int或double)替换。

    比如,实现一个交换模板

    1 template <typename AnyType>
    2 void Swap(AnyType &a,AnyType &b)
    3 {
    4     AnyType temp;
    5     temp=a;
    6     a=b;
    7     b=type;
    8 }

    当交换两个int类型的值时,编译器奖按模板模式创建函数,并用int代替AnyType。同样,当a、b为double类型时,编译器创建的函数也会使用double。

    例子中,template和typename是必须的(typename可用class代替,但是为了区别类与模板,通常使用typename)。类型名可以任意选择,只要遵循c++命名规则即可。

    函数模板同样可以重载,类似重载常规函数定义。

    和常规重载一样,被重载的模板的函数特征必须不同。比如对第一个交换模板进行重载

    1 template <typename AnyType>
    2 void Swap(AnyType *a,AnyType *b,int n)
    3 {
    4     AnyType temp;
    5     temp=a[n];
    6     a[n]=b[n];
    7     b[n]=temp;
    8 }

    重载的函数模板中,最后一个参数的类型为具体类型,而不是范型。

    模板有其局限性,编写的模板有可能无法处理某些类型,比如,下面的代码假定定义了赋值,但如果T为数组,这种假设将不成立

     1 //定义模板函数
     2 template <typename T> //or template <class T>
     3 void f(T a,T b)
     4 {...}
     5 
     6 //当T为数组,下面代码不成立
     7 a=b
     8 
     9 //假设定义了运算符>,但如果T为结构,该假设不成立
    10 if(a>b)
    11 
    12 //为数组名定义了运算符>,但由于数组名为地址,因此比较的是数组的地址。所以,当T为数组、指针或结构,这种假设不成立
    13 T c=a*b;

    另一方面,有时候通用化是有意义的,但c++语法不允许。例如,两个包含坐标位置的坐标结构相加是有意义的,虽然没有为结构定义运算符+。

    一种解决方案是,c++允许重载运算符+,以便能够将其用于特定的结构或类。这样使用运算符+的模板便可以处理重载了运算符+的结构。

    另一种解决方案是,为特定类型提供具体化的模型定义。

    可以提供一个具体化函数定义——成为显示具体化,其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义是,将使用该定义,而不再寻找模板。

    假设定义了如下结构

    struct job
    {
        char name[40];
        double salary;
        int floor;
    }

    假设希望能够交换两个这种结构的内容,原来的模板可以完成。假设只想交换salary和floor成员,而不交换name成员,则需要使用不同的代码,但Swap()的参数将保持不变(两个job结构的引用),因此无法使用模板重载来提供其他代码。

    下面分别是非模板函数、模板函数和具体化的原型

    1 //non template function prototype
    2 void Swap(job &,job &);
    3 
    4 //template prototype
    5 template <typename T>
    6 void Swap(T &,T &);
    7 
    8 //explicit specialization for the job type
    9 template <> void Swap<job>(job &,job &);

    在代码中包含函数模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用模板为特定类型生成函数定义是,得到的是模板实例。例如,函数调用Swap(i,j)导致编译器生成Swap()的一个实例,该实例使用int类型。模板并非函数定义,但模板实例是函数定义。

    编译器选择使用哪个函数版本

    1、创建候选函数列表。其中包含与被调用函数的名称相同的函数和模板函数。

    2、使用候选函数列表创建可行函数列表。这些都是参数数目正确的函数,为此有一个隐式转换序列,其中包括实参类型与相应的形参类型完全匹配的情况。

    3、确定是否有最佳可行函数。

    看得不是很懂,未完待续

  • 相关阅读:
    合并、媒体查询
    混入、命名空间(less)、继承
    函数(内置函数 和 自定义函数)
    运算、单位、转义、颜色
    选择器嵌套、伪类嵌套、属性嵌套(只在Sass中)
    注释、变量、插值、作用域
    二路归并排序java实现
    堆排序Java实现
    和为S的连续正数序列——牛客网(剑指offer)
    transient 与 volatile 笔记
  • 原文地址:https://www.cnblogs.com/Bird-of-Paradise/p/6371470.html
Copyright © 2020-2023  润新知