函数模板初步探究2

参考C++ Primer Plus(中文第五版)P246--258关于函数模板的材料,总结如下:

结合原书中以下代码分析:

//程序清单8.13
// twoswap.cpp -- specialization overrides a template
#include <iostream>
template <class Any>
void Swap(Any &a, Any &b);

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

// explicit specialization 
template <> void Swap<job>(job &j1, job &j2);
void Show(job &j);

int main()
{
    using namespace std;
    cout.precision(2);
    cout.setf(ios::fixed, ios::floatfield);
    int i = 10, j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    cout << "Using compiler-generated int swapper:\n";
    Swap(i,j);    // generates void Swap(int &, int &)
    cout << "Now i, j = " << i << ", " << j << ".\n";

    job sue = {"Susan Yaffee", 73000.60, 7};
    job sidney = {"Sidney Taffee", 78060.72, 9};
    cout << "Before job swapping:\n";
    Show(sue);
    Show(sidney);
    Swap(sue, sidney); // uses void Swap(job &, job &)
    cout << "After job swapping:\n";
    Show(sue);
    Show(sidney);

    return 0;
}

template <class Any>
void Swap(Any &a, Any &b)    // general version
{
    Any temp;
    temp = a;
    a = b;
    b = temp;
}

// swaps just the salary and floor fields of a job structure

template <> void Swap<job>(job &j1, job &j2)  // specialization
{
    double t1;
    int t2;
    t1 = j1.salary;
    j1.salary = j2.salary;
    j2.salary = t1;
    t2 = j1.floor;
    j1.floor = j2.floor;
    j2.floor = t2;
}

void Show(job &j)
{
    using namespace std;
    cout << j.name << ": $" << j.salary
         << " on floor " << j.floor << endl;
}
观察可知,在仅有的一个twoswap.cpp文件中,我们在main函数之前声明了一个常规模板函数,即:

template <class Any>
void Swap(Any &a, Any &b)
还声明了一个显示具体化的模板函数:

// explicit specialization 
template <> void Swap<job>(job &j1, job &j2);
void Show(job &j);
在main函数之后,接着定义了这两个函数。

在这里,有必要讲一下,如果我们在同一个文件中,定义了三个同名的函数,其中一个是常规模板函数,一个是显示具体化的模板函数,一个是常规的非模板函数。那么之间如果存在覆盖的话,优先级是怎样的呢?疑问 书中告诉了我们答案,它说在C++标准中,具体化的模板函数将覆盖常规模板函数,而常规的非模板函数将覆盖具体化的模板函数和常规模板函数。

c++标准还规定了具体化的原型和定义都必须是以template<>打头,通过名称来指出类型。

带代码中包含模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用模板为特定类型生成函数定义时,得到的是模板实例(instantiation)。模板并非函数定义,但是使用特定类型的实例是函数定义。这种实例化方式被称为隐式实例化(implicit instantiation),就是说:编译器在遇到模板函数的声明和定义代码时,并没有给出一个实际的实例定义,它只是获得了关于一个模板函数的介绍,而在遇到调用特定类型的模板函数实例时,编译器才决定以特定类型代替模板函数的模板类型参数,并给出特定类型的实例化定义。哪照这样说,如果我们不调用特定类型的模板函数,模板也就不会实例化了。

但是,现在我们也可以是一个模板函数显示实例化(explicit instantiation),就是说我们可以直接命令编译器创建特定的实例,方式为:

template <> void 函数名<特定类型>(特定类型参数列表)

如:

template void Swap<job>(job &j1, job &j2)

这里注意,显示实例化和显示具体化的意思是不一样的!!!区别在于:

1.显示具体化(explicit specialization)是针对某种特定类型,需要使用与模板函数定义中不同的特定算法时,需要对模板显示具体化,格式例子如下:

template <> void Swap<job>(job &j1, job &j2)  // explicit specialization 显示具体化
2.显示实例化(explicit instantiation)是实现模板函数定义的实例,格式例子如下:

template  void Swap<job>(job &j1, job &j2)  // explicit instantiation 显示实例化
注意显示具体化的声明和定义中代码,在template后面都有一个尖括号<>,而显示实例化都没有。



实际上,如果对同一个模板函数的

        



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值