c++函数模板基础知识

简介: c++函数模板基础知识

导航


1.函数模板及注意事项

2.用模板写个排序函数

3.普通函数与函数模板的区别

4.普通函数与函数模板的调用

5.模板的局限性

———————————————————————————————————


1.函数模板


语法:template< typename T>

typename也可以用class

其中T为通用类型,下面看两个例子

例1:


#include <iostream>
using namespace std;
//交换两个整型函数
void swapint(int &a,int &b)
{
  int temp = a;
  a = b;
  b = temp;
}
//交换两个浮点型函数
void swapDouble(double &a,double &b)
{
  double temp = a;
  a = b;
  b = temp;
}
//要写两个函数再调用
void test01()
{
  int a = 10,b = 20;
  double c = 1.1,d = 2.2;
  swapint(a,b);
  swapDouble(c,d);
  cout<<"a = "<<a<<endl;
  cout<<"b = "<<b<<endl;
  cout<<"c = "<<c<<endl;
  cout<<"d = "<<d<<endl;
}
int main()
{
  test01();
  system("pause");
  return 0;
}



为将两个不同类型的值互换我们要写两个函数,若string类型互换呢,就又要写一个函数,这时候我们就可以用到模板


例2:


#include <iostream>
using namespace std;
//函数模板
template<typename T>
void swapT(T &a,T &b)
{
  T temp = a;
  a = b;
  b = temp;
}
void test02()
{
  int a = 10,b = 20;
  double c = 1.1,d = 2.2;
  //1.自动类型推导
  swapT(a,b);
  //2.显示指定类型
  swapT<double>(c,d);
  cout<<"a = "<<a<<endl;
  cout<<"b = "<<b<<endl;
  cout<<"c = "<<c<<endl;
  cout<<"d = "<<d<<endl;
}
int main()
{
  test02();
  system("pause");
  return 0;
}


这里我们写一个模板套用即可,模板套用有两种方法

1.自动类型推导——(swap(a,b))

2.显示指定类型——(swap< int >(a,b))


注意事项

1.自动推导类型,必须推导出一致的数据类型,才可以使用

2.模板必须确定T的数据类型,才可以使用


例1:(注意1)


#include <iostream>
using namespace std;
//函数模板
template<typename T>
void swapT(T &a,T &b)
{
  T temp = a;
  a = b;
  b = temp;
}
//注意事项
void test()
{
  int a = 10;
  int b = 20;
  char c = 'a';
  swapT(a,b);  //正确
  //swapT(a,c); //错误
}
int main()
{
  test();
  system("pause");
  return 0;
}


例2:(注意2)


#include <iostream>
using namespace std;
//函数模板
template<typename T>
void func()
{
  cout<<"func()调用"<<endl;
}
//注意事项
void test()
{
  func<void>();  //这里必须加数据类型,不然无法调用
}
int main()
{
  test();
  system("pause");
  return 0;
}


———————————————————————————————————


2.利用模板写排序函数


#include <iostream>
using namespace std;
//对不同数据类型数组进行排序
//从大到小,算法为选择排序
//类型char型,int型
template<class T>
//交换数值模板
void myswap(T &a,T &b)
{
  T temp = a;
  a = b;
  b = temp;
}
//排序算法模板
template<class T>
void mysort(T arr[],int len)
{
  for(int i=0;i<len;i++)
  {
  int max = i;
  for(int j=i+1;j<len;j++)
  {
    if(arr[j]>arr[max])
    {
    max = j;
    }
  }
  if(max != i)
  {
    //交换max与i下标
    myswap(arr[i],arr[max]);
  }
  }
}
//提供打印数组模板
template<class T>
void myprintArr(T arr[],int len)
{
  for(int i=0;i<len;i++)
  {
  cout<<arr[i]<<" ";
  }
}
void test01()
{
  //测试char数组
  char charArr[] = "badcfe";
  int len = sizeof(charArr)/sizeof(char);
  mysort(charArr,len);
  myprintArr(charArr,len);
}
void test02()
{
  //测试int数组
  int intArr[] = {7,2,5,4,3,1};
  int len = sizeof(intArr)/sizeof(int);
  mysort(intArr,len);
  myprintArr(intArr,len);
}
int main()
{
  test02();
  system("pause");
  return 0;
}


利用模板写会省力一些


———————————————————————————————————


3.普通函数与函数模板的区别


1.普通函数调用可以发生隐式类型转换

2.函数模板用自动类型推导,不可以发生隐式类型转换

3.函数模板用显示指定类型,可以发生隐式类型转换


例:


#include <iostream>
using namespace std;
//普通函数
int func(int a,int b)
{
  return a+b;
}
//调用模板
template<class T>
T fun(T a, T b)
{
  return a+b;
}
void test02()
{
  int a =10,b =20;
  char c = 'a';
  //1.调用普通函数 可以会发生隐式类型转换
  cout<<func(a,b)<<endl;  
  cout<<func(a,c)<<endl;
  //2.用函数模板自动类型推导,不发生隐式类型转换
  cout<<fun(a,b)<<endl;
  //3.函数模板用显示指定类型,可以发生隐式转换
  cout<<fun<int>(a,c)<<endl;   //这里要提供指定类型
}
int main()
{
  test02();
  system("pause");
  return 0;
}



———————————————————————————————————


4.普通函数与函数模板的调用规则


1.如果函数模板与普通函数都可以调用,优先调用普通函数

2.可以通过空模板参数列表,强制调用 函数模板

3.函数模板也可以重载

4.如果函数模板可以产生更好的匹配,有限调用函数模板


调用规则1


#include <iostream>
using namespace std;
//普通函数
void myprint(int &a,int &b)
{
  cout<<"调用普通函数"<<endl;
}
//函数模板
template<class T>
void myprint(T &a,T &b)
{
  cout<<"函数模板调用"<<endl;
}
void test()
{
  int a=10,b=20;
  myprint(a,b);
}
int main()
{
  test();
  system("pause");
  return 0;
}


结果是先调用普通函数


调用规则2


#include <iostream>
using namespace std;
//普通函数
void myprint(int &a,int &b);
//{
//  cout<<"调用普通函数"<<endl;
//}
//函数模板
template<class T>
void myprint(T &a,T &b)
{
  cout<<"函数模板调用"<<endl;
}
void test()
{
  int a=10,b=20;
  myprint<>(a,b);  //使用空模板参数列表强制调用
}
int main()
{
  test();
  system("pause");
  return 0;
}



调用规则3


若函数模板发生重载,其中调用参数不同即可


调用规则4


#include <iostream>
using namespace std;
//普通函数
void myprint(int a,int b)
{
  cout<<"调用普通函数"<<endl;
}
//函数模板  
template<class T>
void myprint(T a,T b)
{
  cout<<"函数模板调用"<<endl;
}
void test()
{
  char a = 'a',b = 'c';
  myprint(a,b);   
}
int main()
{
  test();
  system("pause");
  return 0;
}



这里会调用函数模板


———————————————————————————————————


5.模板的局限性


若只传入一些普通类型的单个数据,是可以的,若传入数组或者类,就要使用具体化的方法实现


例:


#include <iostream>
using namespace std;
#include <string>
//写一个类
class Person
{
public:
  Person(string name,int age)
  {
  this->name = name;
  this->age = age;
  }
  string name;
  int age;
};
//模板 用于单个普通的类型,数组或者自定义就不行,应该用具体方法实现
template<class T>
bool compare(T a,T b)
{
  if(a==b)
  {
  return true;
  }
  else
  {
  return false;
  }
}
//写一个person类的模板,里面传入的也要改为对应的类型
template<> bool compare(Person p1,Person p2)
{
  if(p1.name == p2.name && p1.age == p2.age)
  {
  return true;
  }
  else
  {
  return false;
  }
}
void test()
{
  int a=10,b =10;
  bool ret = compare(a,b);
  //测试普通的类型
  if(ret)
  {
  cout<<"a == b"<<endl;
  }
  else
  {
  cout<<"a != b"<<endl;
  }
  //测试Person类 
  Person p1("小明",12);
  Person p2("小明",12);
  bool ret1 = compare(p1,p2);
  if(ret1)
  {
  cout<<"p1 == p2"<<endl;
  }
  else
  {
  cout<<"p1 != p2"<<endl;
  }
}
int main()
{
  test();
  system("pause");
  return 0;
}


相关文章
|
1月前
|
编译器 C++
【C++】——初识模板
【C++】——初识模板
32 1
【C++】——初识模板
|
3天前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
12 3
|
1月前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法
16 1
|
1月前
|
C++
c++常见函数及技巧
C++编程中的一些常见函数和技巧,包括生成随机数的方法、制表技巧、获取数字的个位、十位、百位数的方法、字符串命名技巧、避免代码修改错误的技巧、暂停和等待用户信号的技巧、清屏命令、以及避免编译错误和逻辑错误的建议。
19 6
|
1月前
|
存储 C++
c++学习笔记05 函数
C++函数使用的详细学习笔记05,包括函数的基本格式、值传递、函数声明、以及如何在不同文件中组织函数代码的示例和技巧。
28 0
c++学习笔记05 函数
|
1月前
|
编译器 C++
【C++】模板初级
【C++】模板初级
|
1月前
|
安全 编译器 C++
【C++】模板进阶
【C++】模板进阶
|
2月前
|
C++ 运维
开发与运维函数问题之析构函数在C++类中起什么作用如何解决
开发与运维函数问题之析构函数在C++类中起什么作用如何解决
37 11
|
2月前
|
C++ 运维
开发与运维函数问题之C++类的简单示例如何解决
开发与运维函数问题之C++类的简单示例如何解决
53 10
|
1月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
31 0