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

    C++另一种编程思想称为泛型编程,主要采用的技术就是模板

    C++提供两种模板机制:函数模板和类模板。本片文章我们介绍一下函数模板。类模板看另外一篇C++类模板 

    一、函数模板

    1、作用

    建立一个通用函数,其函数返回值和形参类型可以不具体制定。用一个虚拟的类型来表示

    2、语法

    template<typename T>
    函数声明或定义

    template——声明模板

    typename——表明后面的符号是一种数据类型,可以用class来代替

    T——通用的数据类型,可以替换,但一般都是大写字母

    3、注意事项

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

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

    下面的例子来解释上面:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    template<class T>
    void swapp(T &a ,T &b)
    {
        T tmp=a;
        a=b;
        b=tmp;
    }
    template<class T>
    void fun()
    {
        cout<<"I am fine"<<endl;
    }
    int main()
    {
        int a=10,b=20;
        char c='c';
        //使用函数模板第一种方式:自动类型推导
        //swapp(a,b);
    
        //使用函数模板的第二种方式:显式指定类型,这种方法可以发生隐式类型转换
        swapp<int>(a,b);
    
        //自动类型推导,必须要推导出一致的数据类型T才可以使用
        //swapp(a,c);  报错
    
        //模板必须要推导出确定的T的数据类型,才可以使用
        //fun(); //报错,模板不知道数据类型T
        fun<int>(); //正确,随便给一个数据类型就可以
    
        printf("%d %d
    ",a,b);
        return 0;
    }

    二、普通函数与函数模板的调用规则

    1、如果普通函数和函数模板都可以实现,优先调用普通函数

    //如果普通函数和函数模板都可以实现,优先调用普通函数
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    template<class T>
    void swapp(T a ,T b)
    {
        cout<<"function template"<<endl;
    }
    void swapp(int a ,int b); //如果只有函数声明没有函数实现,会报错
    // void swapp(int a ,int b) //如果这个函数存在,那么先调用这个函数
    // {
    //     cout<<"simple template"<<endl;
    // }
    int main()
    {
        int a=10,b=20;
        swapp(a,b);
        return 0;
    }

    2、可以利用空模板参数列表来强制调用函数模板

    //可以利用空模板参数列表来强制调用函数模板
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    template<class T>
    void swapp(T a ,T b)
    {
        cout<<"function template"<<endl;
    }
    void swapp(int a ,int b); //不会报错,因为偶没有调用这个函数
    // void swapp(int a ,int b) //如果这个函数存在,那么先调用函数模板
    // {
    //     cout<<"simple template"<<endl;
    // }
    int main()
    {
        int a=10,b=20;
        //通过空模板参数列表就可以的强制调用函数模板
        swapp<>(a,b);
        return 0;
    }

    3、函数模板也可以发生重载

    4、如果函数模板可以产生更好的匹配,优先调用函数模板

    //如果函数模板可以产生更好的匹配,优先调用函数模板
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    template<class T>
    void swapp(T a ,T b)
    {
        cout<<"function template"<<endl;
    }
    void swapp(int a ,int b); //不会报错,因为没有调用这个函数
    // void swapp(int a ,int b) //如果这个函数存在,那么先调用函数模板
    // {
    //     cout<<"simple template"<<endl;
    // }
    int main()
    {
        char a=10,b=20;
        //因为调用普通函数需要发生隐式类型转换(char->int),而调用函数模板就不需要
        swapp(a,b);
        return 0;
    }

    三、模板的局限性

    有些特定数据类型,需要用具体换方式做特殊实现

    #include <bits/stdc++.h>
    using namespace std;
    class Person
    {
    public:
        Person(string name, int age)
        {
            this->m_Name = name;
            this->m_Age = age;
        }
        string m_Name;
        int m_Age;
    };
    //普通函数模板
    template <class T>
    bool myCompare(T &a, T &b)
    {
        if (a == b)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    //具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
    //具体化优先于常规模板
    template <>
    bool myCompare(Person &p1, Person &p2)
    {
        if (p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    void test01()
    {
        int a = 10;
        int b = 20;
        //内置数据类型可以直接使用通用的函数模板
        bool ret = myCompare(a, b);
        if (ret)
        {
            cout << "a == b " << endl;
        }
        else
        {
            cout << "a != b " << endl;
        }
    }
    void test02()
    {
        Person p1("Tom", 10);
        Person p2("Tom", 10);
        //自定义数据类型,不会调用普通的函数模板
        //可以创建具体化的Person数据类型的模板,用于特殊处理这个类型
        bool ret = myCompare(p1, p2);
        if (ret)
        {
            cout << "p1 == p2 " << endl;
        }
        else
        {
            cout << "p1 != p2 " << endl;
        }
    }
    int main()
    {
        test01();
        test02();
        system("pause");
        return 0;
    }
  • 相关阅读:
    求自变量的取值范围时需要注意的角度
    求正弦型函数的解析式
    求三角形面积的最值[范围]
    三角函数对称性[奇偶性]
    2019届高三理科数学选择填空整理
    均值不等式使用变化
    破解正弦型函数参数的取值范围
    构造法求数列通项公式
    累乘法
    Centos中压缩(zip)和解压(unzip)命令
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/14726061.html
Copyright © 2011-2022 走看看