基本应用

在已知类型的情况下,编译器可以进行数据类型的自动推导,如下例代码,但如果编译器无法自动推导的情况,则不能简单的写 toSwap(a, b);,而是需要在调用时声明类型,如: toSwap(c, d);

  1. #include <iostream>
  2. using namespace std;
  3. template<typename T>//声明T为模板类型,使编译器不报错,typename修改成class也是一样的
  4. void toSwap(T& a,T& b){
  5. T temp = a;
  6. a = b;
  7. b = temp;
  8. }
  9. int main()
  10. {
  11. int a = 1;
  12. int b = 2;
  13. toSwap(a, b);
  14. cout << "a="<<a<< endl;
  15. cout << "b="<<b<< endl;
  16. double c = 1.1;
  17. double d = 2.2;
  18. toSwap(c, d);
  19. cout << "c="<<c<< endl;
  20. cout << "d="<<d<< endl;
  21. return 0;
  22. }

a=2 b=1 c=2.2 d=1.1

普通函数和函数模板同名的调用规则

  • 优先普通函数
  • 可以通过空模板参数列表来强制调用函数模板,即:func<>()
  • 如果函数模板更匹配,则调用函数模板 ```c

    include

    using namespace std;

template void toSwap(T& a,T& b){ T temp = a; a = b; b = temp; }

void toSwap(int& a,int& b){ int temp = a; a = b; b = temp; }

int main() { int a = 1; int b = 2;

  1. toSwap(a, b);//调用普通函数
  2. toSwap<>(a, b);//调用模板函数
  3. char c = 'c';
  4. char d = 'd';
  5. toSwap(c, d);//虽然两个方法都可以执行,普通函数需要强制转化为int,模板函数更匹配,故而会调用模板函数
  6. return 0;

}

  1. <a name="VwMQ3"></a>
  2. ### 模板函数的局限性
  3. 比如比较大小时,虽然类型推断可以做到,但并不是每个数据类型都支持运算符(当然我们也可以通过重载运算符让这个类支持),那么就需要用以下的模板重载的方式来解决:
  4. ```c
  5. #include <iostream>
  6. #include <string>
  7. using namespace std;
  8. template<typename T>
  9. bool toCompare(T& a,T& b){
  10. return a > b;
  11. }
  12. class People{
  13. public:
  14. string name;
  15. int age;
  16. };
  17. //重载模板对People这个类的支持
  18. template<> bool toCompare(People& a,People& b){
  19. return a.age > b.age;
  20. }
  21. int main()
  22. {
  23. int a = 1;
  24. int b = 2;
  25. cout << toCompare(a,b) << endl;
  26. People p{"小明", 20};
  27. People p2{"小红", 30};
  28. cout << toCompare(p, p2) << endl;
  29. return 0;
  30. }