【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 
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 
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 
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 
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 
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表达式】

你可能感兴趣的:(C++指针,c++,函数指针,模板,仿函数)