💪 图像算法工程师,专业从事且热爱图像处理,图像处理专栏更新如下👇:
📝《图像去噪》
📝《超分辨率重建》
📝《语义分割》
📝《风格迁移》
📝《目标检测》
📝《图像增强》
📝《模型优化》
📝《模型实战部署》
📝《图像配准融合》
📝《数据集》
📝《高效助手》
📝《C++》
目录
一、函数模版
函数模板是一种C++语言中提供的泛型编程工具,允许我们在编写函数时使用类型参数来支持多种数据类型,从而提高代码的复用性和可读性。
1.1 函数模版语法
以下是函数模板的基本语法和用法:
定义函数模板:
template <typename T>
T add(T a, T b) {
return a + b;
}
参数解析:
template 是模板的关键字。
typename 或 class 是类型参数的声明关键字(两者等价)。
T 是类型参数,可以用任何合法的标识符代替。
1.2 函数模版例子
这里定义了一个函数模板 add,它可以接受两个相同类型的参数并返回它们的和。
编译器会在调用时根据传入的实参类型自动推导 T。
调用函数模板代码为:
int main() {
cout << add(3, 5) << endl; // 输出 8,T 推导为 int
cout << add(2.5, 3.5) << endl; // 输出 6.0,T 推导为 double
}
编译器根据实参的类型自动生成特定类型的函数。
如果需要显式指定类型,也可以下面方法调用:
cout << add<int>(3, 5) << endl; // 显式指定 T 为 int
1.3 模版中多个类型参数
可以定义多个模板参数,用逗号分隔:
template <typename T1, typename T2>
void display(T1 a, T2 b) {
cout << a << " and " << b << endl;
}
int main() {
display(10, 3.14); // T1 推导为 int,T2 推导为 double
display("Hello", 42); // T1 推导为 const char*,T2 推导为 int
}
1.4 代码
下面是一个完整的模版函数应用例子代码:
#include<iostream>
using namespace std;
#include <ctime>
// 利用模版提供通用的交换函数
// template<class T>
template<typename T> // 只要写了这一行代码,紧跟后面的函数就为模版函数
void mySwap(T& a,T& b)
{
T temp = a;
a = b;
b = temp;
}
// 1、自动类型推导,必须推导出一致的数据类型T,才可以使用
void test01()
{
int a = 10;
int b = 20;
char c = 'c';
mySwap(a,b); // 正确,可以推导出一致的T
// mySwap(a,c); // 错误,推导不出一致的T的类型
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
// 2、模版必须要确定出T的类型,才可使用
// template<class T>
template<typename T>
void func()
{
cout << "func的调用" << endl;
}
void test02()
{
// func(); // 错误,模版不能独立使用,必须确定出T的类型
func<int>(); // 利用显示指定类型的方式,给T一个类型,才可以使用该模版
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
运行代码输出见下:
二、数组排序案例
2.1 需求
利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序;
排序规则从大到小,排序算法为选择排序;
分别利用char数组和int数组进行测试。
2.2 实现
2.2.1 排序算法
排序算法为降序,实现思想为通过遍历数组中数据,先假定一个最大值max索引,与数组中后面数据比较,如果max索引对应的数据小于后面的数据,则交换数据,直至遍历完数组中所有数据。
排序算法的代码见下:
// 排序算法
template<typename T>
void mySort(T arr[] ,int len)
{
for (int i = 0; i < len; i++)
{
int max = i; // 认定最大值的下标
for (int j = i + 1; j < len;j++)
{
// 认定的最大值比遍历出的数值要小,说明j下标的元素才是真正的最大值
if (arr[max] < arr[j])
{
max = j; // 更新最大值下标
}
}
if (max != i)
{
// 交换max和i下标元素
mySwap(arr[max],arr[i]);
}
}
}
2.2.2 交换函数的模版
交换函数模版代码见下:
// 交换函数的模版
template<class T>
void mySwap(T&a,T&b)
{
T temp = a;
a = b;
b = temp;
}
2.2.3 打印输出数组数据模版
重新排序后需要将数组中数据输出查看,将输出封装在printArray()函数模版中,代码见下,这一步用到了上面:1.3 模版中多个类型参数。
// 打印数组模版
template<typename T>
void printArray(T arr[],int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
2.2.4 测试char数组
char数组的测试代码见下:
void test01()
{
// 测试char数组
char charArr[] = "badcfe";
int num = sizeof(charArr) / sizeof(char);
mySort(charArr,num);
printArray(charArr,num);
}
2.2.5 测试int数组
int数组测试代码见下:
void test02()
{
//测试 int数组
int intArr[] = {8,6,4,2,3,9,7,1};
int num = sizeof(intArr) / sizeof(int);
mySort(intArr,num);
printArray(intArr,num);
}
2.3 完整实现代码
2.2小节中各个模块代码整合后的完整代码见下:
2.3.1 代码
#include<iostream>
using namespace std;
#include <ctime>
/*
案例描述:
利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序
排序规则从大到小,排序算法为选择排序
分别利用char数组和int数组进行测试
*/
// 交换函数的模版
template<class T>
void mySwap(T&a,T&b)
{
T temp = a;
a = b;
b = temp;
}
// 排序算法
template<typename T>
void mySort(T arr[] ,int len)
{
for (int i = 0; i < len; i++)
{
int max = i; // 认定最大值的下标
for (int j = i + 1; j < len;j++)
{
// 认定的最大值比遍历出的数值要小,说明j下标的元素才是真正的最大值
if (arr[max] < arr[j])
{
max = j; // 更新最大值下标
}
}
if (max != i)
{
// 交换max和i下标元素
mySwap(arr[max],arr[i]);
}
}
}
// 打印数组模版
template<typename T>
void printArray(T arr[],int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void test01()
{
// 测试char数组
char charArr[] = "badcfe";
int num = sizeof(charArr) / sizeof(char);
mySort(charArr,num);
printArray(charArr,num);
}
void test02()
{
//测试 int数组
int intArr[] = {8,6,4,2,3,9,7,1};
int num = sizeof(intArr) / sizeof(int);
mySort(intArr,num);
printArray(intArr,num);
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
2.3.2 输出
运行上面2.3.1代码,降序后的结果见下:
三、模版的局限性
模型的通用性并不是万能的。
下面代码中将string类型和int类型自定义为Person数据类型,如果直接调用函数模版会出错,需要在调用的函数前加template<> ,见下:
3.1 代码
自定义数据类型及调用函数模版示例代码见下:
// 模版的局限性
#include <iostream>
using namespace std;
#include <string>
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",11);
// 自定义数据类型,不会调用普通的函数模版
// 可以创建具体化的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;
}
3.2 输出
运行3.1中代码,输出见下:
四、总结
以上就是C++中函数模版语法及数组排序案例实现方法,希望能帮到你! 本人参考学习的是黑马程序员,仅作为笔记记录。
感谢您阅读到最后!😊总结不易,多多支持呀🌹 点赞👍收藏⭐评论✍️,您的三连是我持续更新的动力💖
关注下面「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!