函数模板格式

在C++98添加关键字typename之前,C++使用关键字class创建模板。class和typename使用哪个都可以,一般使用typename。

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

重载的模板

  1. template <typename T>
  2. void Swap(T &a, T &b);
  3. template <typename T>
  4. voido Swap(T *a, T *b, int n);

显示具体化(explict specialization)

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

以下是交换函数Swap非模板函数、模板函数和具体化原型

  1. struct job
  2. {
  3. char name[40];
  4. double salary;
  5. int floor;
  6. };
  7. //非模板函数
  8. void Swap(job &, job &);
  9. //模板函数
  10. template <typename T>
  11. void Swap (T &, T &);
  12. //显示具体化 --- 以下两种方式都可以
  13. template <> void Swap<job>(job &, job &);
  14. template <> void Swap(job &, job &);

例子:

  1. #include <iostream>
  2. //函数模板
  3. template <typename T>
  4. void Swap(T &a, T &b);
  5. //显示具体化
  6. template <> void Swap<int>(int &a, int &b);
  7. template <typename T>
  8. void Swap(T &a, T &b)
  9. {
  10. T temp;
  11. temp = a;
  12. a = b;
  13. b = temp;
  14. }
  15. template <> void Swap<int>(int &a, int &b)
  16. {
  17. int temp;
  18. temp = a;
  19. a = b;
  20. b = temp;
  21. }
  22. int main()
  23. {
  24. int x1 = 2, x2 = 3;
  25. Swap(x1, x2); //调用显示具体化
  26. std::cout << "x1:" << x1 << std::endl;
  27. std::cout << "x2:" << x2 << std::endl;
  28. std::string a1 = "123";
  29. std::string a2 = "111";
  30. Swap(a1, a2);
  31. std::cout << "a1:" << a1 << std::endl;
  32. std::cout << "a2:" << a2 << std::endl;
  33. return 0;
  34. }

实例化

在代码中包含函数模板本身并不会生成函数定义,它只是一个用于生成函数定义的方案。编译器使用函数模板为特定类型生成函数定义时,得到的是模板实例。
最初编译器只能通过隐式实例化,来使用模板生成函数定义,也可以显示实例化一个函数定义。
语法:

  1. //实际使用中只需要在使用的位置,声明下就可以, 无需添加额外的定义;
  2. //以Swap函数为例
  3. template void Swap<int>(int, int);

注:试图在同一文件中使用同一类型的显示实例和具体化将出错