IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 185-C++模板编程(函数模板) -> 正文阅读

[C++知识库]185-C++模板编程(函数模板)

1、C++ 函数模板

1.1、函数模板定义

  • 一般使用在开发库中

模板的意义: 对类型也可以进行参数化了

可以定义多个类型参数,中间用逗号隔开
在这里插入图片描述
在这里插入图片描述
也可以用关键字class替代typename
在这里插入图片描述
在这里插入图片描述


1.2、函数模板调用

我们看下面代码:

compare只是一个函数模板名称。我们调用这个compare的时候,肯定是希望这个是模板函数名称。
模板名加上参数列表才是函数名称
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在调用点,编译器又会用double去实例化一份函数代码出来模板函数如下
在这里插入图片描述
在这里插入图片描述
模板的好处:

  • 我们用户只用写一套代码实现逻辑就可以了,至于用什么类型,模板最终用什么类型实例化,我们可以在调用的地方去指定类型,编译器就会从原模板用指定的类型去实例化代码出来。
  • 对于编译器来说,需要待编译的函数并没有减少,每个类型都对应一份函数

只用函数模板的名字,我们也可以进行函数的调用
在这里插入图片描述
在这里插入图片描述
因为 模板的实参推演 => 可以根据用户传入的实参的类型,来推导出模板类型参数的具体类型

注意:

  • 不会再生成和之前生成的模板函数一模一样的函数,不然就成函数的重定义了,会产生符号,每个模板函数的符号只能出现一次,每种模板函数只产生一份,下次需要调用就直接调用之前产生的那个对应的模板函数就可以了
  • 某个类型实例化的函数只会产生一次

下面这种情况是什么样的?

通过第一个传入的实参,推导出T是int整型,通过第二个传入的实参,推导出T是double型,那么T到底是int还是double呢???
在这里插入图片描述
在这里插入图片描述
编译器推导不出来。

  • 另外定义一个新的模板类型参数,a和b用不同的模板类型参数。
  • 我们还可以指定模板类型是int,第一个实参是整型,就传给整型,第二个实参是double,就把double转换成int整型带进去。
    在这里插入图片描述
    在这里插入图片描述

函数模板是无法编译的。 因为不知道T的类型是什么,无法编译。
在这里插入图片描述

  • 函数模板 =》是不进行编译的,因为类型还不知道
  • 模板的实例化 =》函数调用点进行实例化,实例化的模板函数,才是要被编译器所编译的

模板函数:
在这里插入图片描述


1.3、模板偏特化

假设现在我们要比较两个字符串:
在这里插入图片描述
在这里插入图片描述
也是可以比较的

  • 但是,我们在调用这个模板的时候,并没有指定这个参数列表,它就得进行函数模板实参的推演,通过实参推导出T是const char*

得到的实例化的模板函数是:
在这里插入图片描述

  • 显然这是在比较两个字符串的地址的大小,没有意义啊。
  • 我们肯定是想比较它们的字典顺序

实际上,应该调用:
在这里插入图片描述

  • 但是编译器没有办法,因为模板给的是a>b,它只能用你指定的或者推导出来的类型来确定类型,并不能根据具体的类型来改变你的代码。

遇到的问题: 对于某些类型来说,依赖编译器默认实例化的模板代码,代码处理逻辑是有错误的

怎么办?

  • 我们需要给模板提供特例化了。
  • 模板的特例化(专用化) 特殊(不是编译器提供的,而是用户提供的)的实例化
  • 先有模板,才能模板特例化哦

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


再写一个普通函数:

在这里插入图片描述
此时是调用 普通非模板函数?还是调用模板特例化函数?

在这里插入图片描述
调用普通非模板函数!


在这里插入图片描述
如果写成这样,编译器不会将compare当成函数名!
因为函数名后面不可能 + <> 符号的,只有模板名后面才能 + <>!

在这里插入图片描述
调用特例化的模板函数!

	//函数模板实参的推演 T const char*
	//对于某些类型来说,依赖编译器默认实例化的模板代码,代码处理逻辑是有错误的
	//编译器优先把compare处理成函数名字,没有的话,才去找compare模板
	compare("aaa", "bbb");
	compare<const char*>("aaa", "bbb");


我们再看,我们在写多文件的时候,要注意:

  • 我们在一个文件中定义模板,在另一个文件中声明模板,然后使用它。
  • 会发生链接错误

在这里插入图片描述
在这里插入图片描述
C++模板.cpp
在这里插入图片描述
在这里插入图片描述
运行结果:

  • 出现链接错误!
    在这里插入图片描述
    在这里插入图片描述
    没有找到compare的int和double类型的。

但是下面这两个找到了,因为一个是普通函数,一个是模板的特例化
在这里插入图片描述
测试:

  • 将上面的屏蔽掉,只留最后两个,同时在文件中声明普通函数和模板的特例化函数:
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

在链接的时候,找下在其他文件定义的地方,可以找到!!!
在这里插入图片描述


**问题:**为什么int和double的找不到?
在这里插入图片描述

  • 模板本身是不编译的,类型不知道;
  • 调用的时候才会进行编译!!

生成并编译下面的模板函数:
在这里插入图片描述

  • 模板代码是不能在一个文件中定义,在另外一个文件中使用的
  • 模板代码调用之前,一定要看到模板定义的地方,这样的话,模板才能够进行正常的实例化,产生能够被编译器编译的代码
  • 所以,模板代码都是放在头文件当中的,然后在源文件当中直接进行#include包含(例如STL库中的)
  • include是在预编译的过程中,把头文件的代码直接在当前源文件中展开

如果一定要在多个文件调用,还是有办法的。
在这里插入图片描述
不用看调用点,直接用用户指定的类型进行模板实例化。
在这里插入图片描述

1.4、模板的非类型参数

  • 必须是整数类型整数,其他类型的指针地址/引用都可以
  • 都是常量,只能使用,而不能修改
#include <iostream>
using namespace std;

template<typename T, int SIZE>
void sort(T* arr)
{
	for (int i = 0; i < SIZE - 1; ++i)
	{
		for (int j = 0; j < SIZE - 1 - i; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 12,5,7,89,32,21,35 };
	const int size = sizeof(arr) / sizeof(arr[0]);//常量表达式 
	sort<int, size>(arr);
	//sort<int, 7>(arr);
	for (int val : arr)
	{
		cout << val << " ";
	}
	cout << endl;
	return 0;
}

这两个是等价的!
在这里插入图片描述
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:18:51  更:2022-05-12 16:19:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:08:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码