• c++ - 模板(一)


    文章目录


    一、函数模板

    1、概念

    函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定 类型版本。

    2、原理

    函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模
    板就是将本来应该我们做的重复的事情交给了编译器。

    3、格式

    template<typename T1, typename T2,......,typename Tn> //template
    返回值类型 函数名(参数列表){}
    
    • 1
    • 2

    4、简单使用
    实现一个任何加法模板

    template<class T>
    T Add(T a, T b)
    {
    	return a + b;
    }
    
    int main()
    {
    	//整形相加
    	Add(1, 2);
    	//浮点型相加
    	Add(1.1, 2.2);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数以供 调用。比如:当用double类型使用函数模板时,编译器通过对实参类型的推演,将T确定为double类型,然后产生一份专门处理double类型的代码。

    5、不同的实例化
    (1)隐式实例化
    就是通过编译器根据传入的实参进行推导
    如:

    /整形相加
    //根据参数自行推导为int类型
    Add(1, 2);
    //浮点型相加
    //根据参数自行推导为double类型
    Add(1.1, 2.2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    但是通过隐式类型推导是不能使其出现歧义
    如:

    //一个为int 一个为double
    Add(1, 1.1);
    
    • 1
    • 2

    在这里插入图片描述
    对于上述情况有两个解决方案:使用强制类型转换、使用显式实例化

    (2)显式实例化

    格式:Add(函数名)<显式的类型>(参数列表)

    template<class T>
    T Add(T a, T b)
    {
    	return a + b;
    }
    
    //显式实例化
    int main()
    {
    	//int
    	cout<<Add<int>(1, 1)<<endl;
    
    	//double
    	cout<<Add<double>(1.1, 1.1) << endl;
    
    	//int
    	cout<<Add<int>(1, 1.1) << endl;
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述
    6、模板匹配
    规则:谁能更好的匹配就会使用哪个模板,有具体类型的就优先使用。

    //int 类型的相加
    int Add(int a, int b)
    {
    	cout << "int Add(int a, int b)" << endl;
    	return a + b;
    }
    
    //模板一(相同类型相加)
    template<class T>
    T Add(T a, T b)
    {
    	cout << "T Add(T a, T b)" << endl;
    	return a + b;
    }
    
    //模板2 (可以实现不同类型)
    template<class T1, class T2>
    auto Add(T1 a, T2 b)
    {
    	cout << "auto Add(T1 a, T2 b)" << endl;
    	return a + b;
    }
    
    int main()
    {
    	//都用int类型
    	Add(1, 1);
    
    	//都用double类型 
    	Add(1.1, 1.1);
    
    	//一个double类型,一个int类型
    	Add(1.1, 1);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

    如果想让其不使用具体的函数,可以使用显式调用
    如:

    //都用int类型
    	Add(1, 1);//调用具体的函数
    	Add<int>(1, 1);//调用模板的
    
    • 1
    • 2
    • 3

    二、类模板
    1、类模板的定义格式

    template<class T1, class T2, ..., class Tn> //typename T1....
    class 类模板名
    {
     // 类内成员定义
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、类模板的实例化
    (1)类模板只能显式实例化

    template<class T>
    class A
    {
    public:
    private:
    	T _a;
    };
    
    int main()
    {
     //实例化,类型为 A
    	A<int> a;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    (2)类模板中的成员函数类外实现

    //类模板
    template<class T>
    class A
    {
    public:
    	T get();
    private:
    	T _a;
    };
    
    //类外实现
    template<class T>
    T A<T>::get()
    {
    	return _a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    (3)注意:不要将类模板的声明和定义分离到不同文件,会出现链接错误。

  • 相关阅读:
    设计海报都有哪些好用的软件推荐
    操作系统 —— 处理机调度与死锁
    GO请求参数规则校验(自定义校验规则、规则中文化)
    怎么从0到1实现一个PHP框架?
    完全可复制、经过验证的 Go 工具链
    侯捷课程笔记(一)(传统c++语法,类内容)
    决策树oo
    Lim接口测试平台开展自动化的优势
    任意文件下载(读取)
    spring 获取ioc容器,从容器中获取bean
  • 原文地址:https://blog.csdn.net/2302_79539362/article/details/138038189