C++的函数进化小结
函数
有这样一个问题
#include <iostream> int main () { int IntArray = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; return 0 ; }
那么很自然的给出解法
#include <iostream> int CountMatch (int * start, int * end) { int sum = 0 ; for (; start < end ; start++) { if (*start > 20 ) sum++; } return sum; } int main () { int IntArray[] = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; std::cout<<"Matches: " <<CountMatch (IntArray,IntArray+20 )<<std::endl; return 0 ; }
函数指针
这个时候的需要满足 统计大于10的数字 或者 统计小于35的数字 ,那么可以将*start > 20这一段包装一下
#include <iostream> int CountMatch (int * start, int * end, bool (*ConditionFunc)(const int &)) { int sum = 0 ; for (; start < end ; start++) { if (ConditionFunc (*start)) sum++; } return sum; } bool bGreat20 (const int &num) { return num > 20 ; }bool bGreat10 (const int &num) { return num > 10 ; }bool bLess35 (const int &num) { return num < 35 ; }int main () { int IntArray[] = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; std::cout<<"Greater than 20 Matches: " <<CountMatch ( IntArray, IntArray+20 , bGreat20 )<<std::endl; std::cout<<"Greater than 10 Matches: " <<CountMatch ( IntArray, IntArray+20 , bGreat10 )<<std::endl; std::cout<<"Greater than 20 Matches: " <<CountMatch ( IntArray, IntArray+20 , bLess35 )<<std::endl; return 0 ; }
图片上的代码有点小问题
在c语言中可以这样写,虽然编译会有警告,但是仍然可以生成。
#include <stdio.h> int CountMatch (int * start, int * end, void *function_pointer(int )) { int sum = 0 ; for (; start < end ; start++) { if (function_pointer(*start)) sum++; } return sum; } int Pointer (int start) { printf ("Happy\n" ); return 1 ; } int main () { int IntArray[] = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; printf ("Matches: %d\n" ,CountMatch(IntArray,IntArray+20 , Pointer)); return 0 ; }
在c中伴随着指针的引用*p和解引用&p,C 对指针的类型安全性进行了更严格的限制。C++中的指针类型必须与所指向的对象类型匹配,不允许进行隐式类型转换。这可以帮助减少潜在的类型错误和编程错误。
函数模板
上面的函数只能支持int,使用函数模板能让他支持更多类型
#include <iostream> template <typename T> int CountMatch (T* start, T* end, bool (*ConditionFunc)(const T &)) { int sum = 0 ; for (; start < end ; start++) { if (ConditionFunc (*start)) sum++; } return sum; } bool bGreat20 (const int &num) { return num > 20 ; }bool bGreat10 (const int &num) { return num > 10 ; }bool bLess35 (const int &num) { return num < 35 ; }bool bTiny (const std::string &val) { return val.size () <= 3 ; }int main () { int IntArray[] = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; std::string StrArray[] = {"Hello" ,"world" ,"This" ,"is" ,"a" ,"test" }; std::cout<<"Greater than 20 Matches: " <<CountMatch ( IntArray, IntArray+20 , bGreat20 )<<std::endl; std::cout<<"Greater than 10 Matches: " <<CountMatch ( IntArray, IntArray+20 , bGreat10 )<<std::endl; std::cout<<"Greater than 20 Matches: " <<CountMatch ( StrArray, StrArray+6 , bTiny )<<std::endl; return 0 ; }
仿函数
在条件中如果需要处理用户传入的数字怎么办
仿函数(Functor)是C++中的一个概念,指的是可以像函数一样使用的对象。它实际上是一个类或结构体,重载了函数调用运算符 operator(),使得对象可以像函数一样进行调用操作。
chatGPT给了我这样一个例子
#include <iostream> class AddFunctor {public : int operator () (int a, int b) { return a + b; } }; int main () { AddFunctor add; int result = add (3 , 4 ); std::cout << "Result: " << result << std::endl; return 0 ; }
在这里可以这样写
template <typename T>struct Greater { T mVal; explicit Greater (T value) : mVal(value){ } bool operator () (const T &val) const { return val>mVal; } };
explicit:通过在单参数构造函数前添加 explicit 关键字,可以防止编译器在需要进行类型转换的情况下自动调用该构造函数。
operator:仿函数的实现,使得对象可以像函数一样进行调用操作。
抓函数中生成一个对象(该标准仅在c++11及以上支持),但是这样函数指针就没法用了
Greater<int > greater20{20 };
可以学习标准库中的操作将模板持续下去
template <typename T, typename fCompare>int CountMatch (T* start, T* end, fCompare ConditionFunc) { int sum = 0 ; for (; start < end ; start++) { if (ConditionFunc (*start)) sum++; } return sum; }
最后程序
#include <iostream> template <typename T, typename fCompare>int CountMatch (T* start, T* end, fCompare ConditionFunc) { int sum = 0 ; for (; start < end ; start++) { if (ConditionFunc (*start)) sum++; } return sum; } template <typename T>struct Greater { T mVal; explicit Greater (T value) : mVal(value){ } bool operator () (const T &val) const { return val>mVal; } }; int main () { int IntArray[] = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; std::string StrArray[] = {"Hello" ,"world" ,"This" ,"is" ,"a" ,"test" }; Greater<int > greater20{20 }; std::cout<<"Greater than 20 Matches: " <<CountMatch ( IntArray, IntArray+20 , greater20 )<<std::endl; return 0 ; }
lambda表达式
这个我再Qt上用的挺多的,他是匿名函数的实现
int main () { int IntArray[] = { 12 , 13 , 35 , 16 , 6 , 5 , 5 , 12 , 4 , 13 , 38 , 35 , 37 , 33 , 35 , 15 , 36 , 14 , 13 , 12 }; auto greater20 = [](auto &val) -> bool { return val > 20 ; }; std::cout<<"Greater than 20 Matches: " <<CountMatch ( IntArray, IntArray+20 , greater20 )<<std::endl; return 0 ; }