zoukankan      html  css  js  c++  java
  • C++ 函数模板用法

    泛型编程概念:不考虑具体数据类型的编程方式;

    函数模板:

    1.提供一种特殊的函数可用不同类型进行调用;

    2.与普通函数很相似,区别是类型可被参数化;

    template <typename T>   //template关键字用于声明开始进行泛型编程
    void Swap(T &a, T &b)   //typename关键字用于声明泛指类型
    {
         T tmp = a;
            a = b;
            b = tmp;       
    }
    

    函数模板的应用:

    1.自动类型推导调用;

    2.具体类型显示调用;

    int a = 3;
    int b = 4;
    Swap(a,b);                    //自动类型推导调用
    
    float fa = 5.5;
    float fb = 8.8;
    Swap<float>(fa, fb)          //具体类型显示调用,用float替换参数类型T
    

    使用演示:

    #include <iostream>
    
    template <typename T>                           //交换变量
    void Swap(T& a, T& b)
    {
    	T t;
    	t = a;
    	a = b;
    	b = t;
    }
    
    template <typename T>                       //将数组内容从小到大排序
    void SelectMin(T array[], int size)
    {
    	for (int i = 0; i < size; i++)
    	{
    		T Min = array[i];
    		int Index = 1;
    		for (int j = i + 1; j < size; j++)
    		{
    			if (Min > array[j])
    			{
    				Min = array[j];
    				Index = j;
    				Swap(array[i], array[Index]);
    			}
    		}
    		
    	}
    }
    
    
    int main()
    {
    	int a = 3;
    	int b = 8;
    	Swap(a, b);       //自动类型推导
    	std::cout << "a = " << a << std::endl;
    	std::cout << "b = " << b << std::endl;
    
    	float fa = 3.4;
    	float fb = 8;
    	Swap<float>(fa, fb); //具体类型显示调用
    	std::cout << "fa = " << fa << std::endl;
    	std::cout << "fb = " << fb << std::endl;
    
    	char ca = 'a';
    	char cb = 'b';
    	Swap(ca, cb);
    	std::cout << "ca = " << ca << std::endl;
    	std::cout << "cb = " << cb << std::endl;
    
    	int array[] = {4, 3, 1, 2, 45};
    	SelectMin(array, 5);
    	for (int i = 0; i < 5; i++)
    	{
    		std::cout << "i = " << array[i] << std::endl;
    	}
    
    	char array2[] = { 'a', 'f', 'e', 'c', 'b' };
    	SelectMin(array2, 5);
    	for (int i = 0; i < 5; i++)
    	{
    		std::cout << "i = " << array2[i] << std::endl;
    	}
    	return 0;
    }
    

      

    函数模板的深入理解:

    -- 编译器并不会把函数模板处理成能够处理任意类型的函数;

    --编译器从函数模板通过具体类型产生不同的函数;

    --编译器会对函数模板进行两次编译;

      --在声明的地方对模板代码本身进行编译

      --在调用的地方对参数替换后的代码进行编译

    当函数模板遇到函数重载:

    --C++编译器优先考虑普通函数;

    --如果函数模板可以产生一个更好的匹配,那么选择模板;

    --通过空模板实参列表的语法限定编译器只通过模板匹配;

    注意事项:

    --函数模板不允许自动类型转化;

    --普通函数能够进行类型转化;

    int Max(int a, int b)              //普通函数
    {
       return a > b ? a : b;  
    }
    
    template <typename T>    //模板函数
    T Max(T a, T b)
    {
       return  a > b ? a : b;  
    }
    
    int main()
    {
       int a = 4;
       int b = 8;
       Max(a,b);        //调用普通函数
       Max<>(a,b);  //空模板实参列表,只能调用函数模板
     
       float fa = 5.5;
       float fb = 8.8;
       Max(fa,fb);    //调用普通函数会进行类型转换,通过函数模板会产生一个更好的匹配
     
       Max('a',100);//返回结果是调用普通函数a的ASCII码,因为‘a’是字符型,100是整形,与函数模板不匹配
    return 0; }

     

    函数模板可以定义多个类型的参数:

    template <typename T1, typename T2, typename RT>
    RT Add(T1 a, T2 b)         //RT作为返回类型
    {
         return static_cast<RT>(a+b)
    }
    
    cout<<Add<char, float, double>('a', 100)<<endl;
    当声明的类型参数作为返回值类型,无法推导出返回值类型!
    即Add('a', 100)这样自动推导调用编译器会报错;
    
    不完美处理方案:
    template <typename RT, typename T1, typename T2>
    RT Add(T1 a, T2 b)         //RT作为返回类型
    {
         return static_cast<RT>(a+b)
    }
    
    cout<<Add<double>('a', 100)<<endl;   //将返回类型放在第一个参数,只显示的列出返回值类型,其它2个参数编译器自动推导
    

      

  • 相关阅读:
    2019 蓝桥杯国赛 B 组模拟赛 D. 程序设计:公约数
    2019长安大学ACM校赛网络同步赛 M LCM (数论)
    CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
    CCPC-Wannafly Winter Camp Day1 流流流动 (树形dp)
    CCPC-Wannafly Winter Camp Day1 (Div2) 吃豆豆 (DP)
    CCPC-Wannafly Winter Camp Day1 (Div2, onsite) 夺宝奇兵
    CCPC-Wannafly Winter Camp Day1 爬爬爬山 (最短路)
    Comet OJ
    Comet OJ
    hdu-Danganronpa(AC自动机)
  • 原文地址:https://www.cnblogs.com/asce/p/11145025.html
Copyright © 2011-2022 走看看