当前位置: 首页 > article >正文

【C++函数的进化】函数指针,模板,仿函数,lambda表达式

/**
 * @poject          
 * @author			jUicE_g2R(qq:3406291309)
 * @file            C++函数的进化
 * 
 * @language        C++
 * @EDA				Base on VS2022
 * @editor			Obsidian(黑曜石笔记软件)
 * 
 * @copyright		2023
 * @COPYRIGHT	    原创学习笔记:转载需获得博主本人同意,且需标明转载源
 */
  • 函数进化()
    函数 -> 函数指针 -> 函数模板 -> 仿函数->lambda表达式

文章目录

  • 1 函数
  • 2 函数指针
  • 3 函数模板
  • 4 仿函数(函数对象)
  • 5 lambda表达式简化

1 函数

#include <iostream>
using std::cin;
using std::cout;
using std::string;
typedef int* pInt;

int Count_Match20_Elem(pInt pSta, pInt pEnd) {
	int res = 0;
	for (; pSta != pEnd; ++pSta)
		if (*pSta > 20)
			res++;
	return res;
}
int Count_Match25_Elem(const pInt pSta, const pInt pEnd) { // 这样会造成代码冗余
	int res = 0;
	for (; pSta != pEnd; ++pSta)
		if (*pSta > 25)
			res++;
	return res;
}

int main(int* argc, char* argv[]){
	int arr[] = { 11,16,21,19,17,30 };
	cout << Count_Match20_Elem(arr, arr + sizeof(arr) / 4);	// sizeof(arr):得到的是arr数组的 总字节大小 ,而不是arr中元素的个数(一个int元素占4bit)
	return 0;
}

2 函数指针

  • 函数 变成 变量
  • “行为” “数据化”
#include <iostream>
using std::cin;
using std::cout;
using std::string;

//将判断处的代码(独特之处)重新封装为函数
bool isGreater20(const int& val) { return val > 20; }
bool isGreater25(const int& val) { return val > 25; }
int CountMatchElem(int* pSta, int* pEnd, bool(*pComp)(const int&)) {
	int res = 0;
	for (; pSta != pEnd; ++pSta)
		if (pComp(*pSta))	//pComp为函数指针;括号里的传入参数为 指针变量pSta指向的对象
			res++;
	return res;
}

int main(int* argc, char* argv[]){
	int arr[] = { 11,16,21,19,17,30 };
	cout << CountMatchElem(arr, arr + sizeof(arr)/ sizeof(int), isGreater20);
	return 0;
}

3 函数模板

  • 独立于类型的函数
  • 可产生函数特定类型的版本
#include <iostream>
using std::cin;
using std::cout;
using std::string;

bool isGreater20(const int& val) { return val > 20; }
bool isGreater25(const int& val) { return val > 25; }
bool isTinyStr(const string& str) { return str.size() <= 3; }
template<typename DataType>
int CountMatchElem(DataType* pSta, DataType* pEnd, bool(*pComp)(const DataType&)) {
	int res = 0;
	for (; pSta != pEnd; ++pSta)
		if (pComp(*pSta))	//pComp为函数指针;括号里的传入参数为 指针变量pSta指向的对象
			res++;
	return res;
}
int main(int* argc, char* argv[]){
	int arr[] = { 11,16,21,19,17,30 };
	string strs[] = { "abc", "bcde", "cdefg", "de", "efg" };
	cout << CountMatchElem<int>(arr, arr + sizeof(arr)/ sizeof(int), isGreater20);
	cout << CountMatchElem<string>(strs, strs + sizeof(strs) / sizeof(strs[0]), isTinyStr);
	
	return 0;
}

4 仿函数(函数对象)

  • 定义了调用操作符
  • 行为类似函数的对象
#include <iostream>
using std::cin;
using std::cout;
using std::string;

template<typename T>
struct Greater { // 定义仿函数
	T StdVal;
	explicit Greater(T val) : StdVal(val) {} // 构造函数初始化StdVal
	bool operator()(const T& val) const { return val > StdVal; } // 重载函数调用操作符
};

template<typename DataType>
int CountMatchElem(DataType* pSta, DataType* pEnd, bool(*pComp)(const DataType&)) {
	int res = 0;
	for (; pSta != pEnd; ++pSta)
		if (pComp(*pSta))	//pComp为函数指针;括号里的传入参数为 指针变量pSta指向的对象
			res++;
	return res;
}

int main(int* argc, char* argv[]){
	int arr[] = { 11,16,21,19,17,30 };
	Greater<int> gtr20(20); // 实例化一个函数对象,将判断阈值设为20
	cout << CountMatchElem(arr, arr + sizeof(arr) / sizeof(int), gtr20); // 这里会报错!!!
	return 0;
}
  • 更改
template<typename DataType, typename pFunc>
int CountMatchElem(DataType* pSta, DataType* pEnd, pFunc pComp) 

5 lambda表达式简化

#include <iostream>
using std::cin;
using std::cout;
using std::string;

template<typename DataType, typename pFunc>
int CountMatchElem(DataType* pSta, DataType* pEnd, pFunc pComp) {
	int res = 0;
	for (; pSta != pEnd; ++pSta)
		if (pComp(*pSta))	//pComp为函数指针;括号里的传入参数为 指针变量pSta指向的对象
			res++;
	return res;
}

int main(int* argc, char* argv[]){
	int arr[] = { 11,16,21,19,17,30 };
	auto gtr20 = [](auto& val) -> bool {return val > 20; };
	cout << CountMatchElem(arr, arr + sizeof(arr) / sizeof(int), gtr20); // 这里会报错
	return 0;
}

  • 参考视频源【C++函数的进化 函数→函数指针→函数模板→仿函数|函数对象→lambda表达式】

http://www.kler.cn/a/132846.html

相关文章:

  • 【windows】05-windows系统级深度隐藏文件方法
  • 1 设计模式原则之开闭原则
  • java常用工具包介绍
  • 从零开始学习 sg200x 多核开发之 eth0 MAC 地址修改
  • wordpress使用相关
  • 023、ELK 从入门到实践
  • 【开源】基于JAVA的校园失物招领管理系统
  • 简单的python爬虫工具,B站视频爬虫
  • 高校教师资格证备考
  • 综述:目标检测二十年(机翻版)(未完
  • 读取PDF中指定数据写入EXCEL文件
  • 代码随想录 Day47 动态规划15 LeetCode T583 两个字符串的删除操作 T72 编辑距离
  • golang 上传图片 --chatGPT
  • 紫色调城市和奔跑人物剪影背景工会工作总结汇报PPT模板
  • 【数据结构】顺序表详解
  • MFC 常用控件
  • AR眼镜_单目光波导VS双目光波导方案
  • css制作瀑布流布局
  • Debian 11 更新 Node.js 版本
  • mysql8创建用户并授予权限和移除权限
  • SystemVerilog学习 (11)——覆盖率
  • 十二、Docker的简介
  • srs webrtc推拉流环境搭建(公网)
  • 赤壁
  • 【Java 进阶篇】唤醒好运:JQuery 抽奖案例详解
  • 【C语言】数组下标为啥从0开始?下标越界访问一定报错吗?