• 函数模板做函数参数


    一、函数模板申明、生成及注意事项

    1.1函数模板申明

    函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计。它的最大特点是把函数使用的数据类型作为参数。

    函数模板的声明形式为:

      template<typename 数据类型参数标识符>

      <返回类型><函数名>(参数表)

        {

            函数体

        }

      其中,template是定义模板函数的关键字;template后面的尖括号不能省略;typename(或class)是声明数据类型参数标识符的关键字,用以说明它后面的标识符是数据类型标识符。这样,在以后定义的这个函数中,凡希望根据实参数据类型来确定数据类型的变量,都可以用数据类型参数标识符来说明,从而使这个变量可以适应不同的数据类型。

    函数模板只是声明了一个函数的描述即模板,不是一个可以直接执行的函数,只有根据实际情况用实参的数据类型代替类型参数标识符之后,才能产生真正的函数。关键字typename也可以使用关键字class,这时数据类型参数标识符就可以使用所有的C++数据类型。

    1.2模板函数的生成

      函数模板的数据类型参数标识符实际上是一个类型形参,在使用函数模板时,要将这个形参实例化为确定的数据类型。将类型形参实例化的参数称为模板实参,用模板实参实例化的函数称为模板函数。模板函数的生成就是将函数模板的类型形参实例化的过程。

    1.3函数模板使用应注意问题

      1)函数模板允许使用多个类型参数,但在template定义部分的每个形参前必须有关键字typename或class,即:

        template<class 数据类型参数标识符1,…,class 数据类型参数标识符n>

        <返回类型><函数名>(参数表)

        {

             函数体

        }

      2)在template语句与函数模板定义语句<返回类型>之间不允许有别的语句。如下面的声明是错误的:

    1 template<class T>
    2 int I;
    3 T min(T x,T y)
    4 
    5 {
    6 
    7    函数体
    8 
    9 }

      3)模板函数类似于重载函数,但两者有很大区别:函数重载时,每个函数体内可以执行不同的动作,但同一个函数模板实例化后的模板函数都必须执行相同的动作。

    二、函数模板的调用

    函数模板调用通常有两种调用方式:

      1)myswap<float>(a,b);//显示类型调用;

      2)myswap(a,b);//自动数据类型推导;

    三、函数模板做参数实例

      3.1对一个数组进行排序,未使用模板

     1 #include<iostream>
     2 using namespace std;
     3 
     4 //排序整型数组、字符串数组
     5 int mySort(int *arr, int len)
     6 {
     7     int tmp = 0;
     8     if (arr==NULL)
     9     {
    10         return -1;
    11     }
    12     for (int i = 0; i < len; i++)
    13     {
    14         
    15         for (int j = i+1; j < len; j++)
    16         {
    17             if (arr[i]<arr[j])
    18             {
    19                 tmp = arr[i];
    20                 arr[i] = arr[j];
    21                 arr[j] = tmp;
    22             }
    23         }
    24     }
    25 
    26     return 0;
    27 }
    28 int myPrint(int *arr,int len)
    29 {
    30     
    31     for (int i = 0; i < len; i++)
    32     {
    33         cout << arr[i] << "    " ;
    34     }
    35     cout << endl;
    36     return 0;
    37 }
    38 void main()
    39 {
    40     int arr[] = {11,33,4,55,66,78,98};
    41     int size = sizeof(arr) / sizeof(*arr);
    42     printf("排序之前
    ");
    43     myPrint(arr,size);
    44     printf("排序之后
    ");
    45     mySort(arr, size);
    46     myPrint(arr,size);
    47     system("pause");
    48 }

    3.2函数模板做参数实例

     1 #include<iostream>
     2 using namespace std;
     3 
     4 //排序整型数组、字符串数组
     5 template<typename T,typename T2>
     6 int mySort(T *arr, T2 len)
     7 {
     8     T tmp = 0;
     9     if (arr==NULL)
    10     {
    11         return -1;
    12     }
    13     for (T i = 0; i < len; i++)
    14     {
    15         
    16         for (T j = i+1; j < len; j++)
    17         {
    18             if (arr[i]<arr[j])
    19             {
    20                 tmp = arr[i];
    21                 arr[i] = arr[j];
    22                 arr[j] = tmp;
    23             }
    24         }
    25     }
    26 
    27     return 0;
    28 }
    29 template<typename T, typename T2>
    30 int myPrint(T *arr,T len)
    31 {
    32     
    33     for (T i = 0; i < len; i++)
    34     {
    35         cout << arr[i] << "    " ;
    36     }
    37     cout << endl;
    38     return 0;
    39 }
    40 void main()
    41 {
    42     int arr[] = {11,33,4,55,66,78,98};
    43     int size = sizeof(arr) / sizeof(*arr);
    44     printf("排序之前
    ");
    45     myPrint<int ,int >(arr,size);//显示调用
    46     printf("排序之后
    ");
    47     mySort(arr, size);//自动调用
    48     myPrint<int,int>(arr,size);
    49     system("pause");
    50 }

     四、函数模板与普通函数的差异

      1)函数模板不允许自动类型转换;

      2)普通函数能够进行自动类型转换。

      函数模板可以像普通函数一样被重载,如果一个程序中同时存在函数模板和普通函数,C++编译器有限考虑调用普通函数,如果函数模板可以产出更好的匹配,则选择函数模板。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int Max(int a, int b)
     5 {
     6     cout << "int max(int a,int b)" << endl;
     7     return a > b ? a : b;
     8 }
     9 
    10 template<typename T>
    11 T Max(T a, T b)
    12 {
    13     cout << "T max(T a,T b)" << endl;
    14     return a > b ? a : b;
    15 }
    16 
    17 template<typename T>
    18 T Max(T a, T b, T c)
    19 {
    20         cout << "T Max(T a, T b, T c)" << endl;
    21         return a > b ? a : b;
    22 }
    23 void main()
    24 {
    25     int a = 10;
    26     int b = 20;
    27     cout << Max(a,b) << endl;//当函数模板和普通函数都符合调用规则,优先选择普通函数
    28     cout << Max<>(a, b) << endl;//若显示使用函数模板,则调用函数模板
    29     cout << Max(1.0, 2.0, 3.0) << endl;//函数的重载
    30     cout << Max('a', 100);//调用普通函数,可以隐式转换
    31     system("pause");
    32
  • 相关阅读:
    BootStrap行内编辑
    NPOI学习笔记
    仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'Address'中的标识列指
    .Net MVC发布出错 Server Error in '/' Application.
    C# 新特性
    System.Runtime.InteropServices.COMException:“服务器出现意外情况。 (异常来自
    BootStrap的表格加载json数据,并且可以搜索,选择
    NPOI导入导出Excel
    读取Easy UI的DATa grid里面的所有数据
    C# 导出Excel
  • 原文地址:https://www.cnblogs.com/506941763lcj/p/11279062.html
Copyright © 2020-2023  润新知