建设公司门户网站建设方案,的物app,那些行业需要做网站,ps自学网官方网站https://www.cnblogs.com/decade-dnbc66/p/5347088.html内容整理自国外C教材先考虑一个简单的例子#xff1a;假设有一个vectorstring#xff0c;你的任务是统计长度小于5的string的个数#xff0c;如果使用count_if函数的话#xff0c;你的代码可能长成这样#…https://www.cnblogs.com/decade-dnbc66/p/5347088.html内容整理自国外C教材先考虑一个简单的例子假设有一个vectorstring你的任务是统计长度小于5的string的个数如果使用count_if函数的话你的代码可能长成这样
1 bool LengthIsLessThanFive(const string str) {
2 return str.length()5;
3 }
4 int rescount_if(vec.begin(), vec.end(), LengthIsLessThanFive);其中count_if函数的第三个参数是一个函数指针返回一个bool类型的值。一般的如果需要将特定的阈值长度也传入的话我们可能将函数写成这样
1 bool LenthIsLessThan(const string str, int len) {
2 return str.length()len;
3 }这个函数看起来比前面一个版本更具有一般性但是他不能满足count_if函数的参数要求count_if要求的是unary function仅带有一个参数作为它的最后一个参数。所以问题来了怎么样找到以上两个函数的一个折中的解决方案呢这个问题其实可以归结于一个data flow的问题要设计这样一个函数使其能够access这个特定的length值回顾我们已有的知识有三种解决方案可以考虑
1、函数的局部变量局部变量不能在函数调用中传递而且caller无法访问。
2、函数的参数这种方法我们已经讨论过了多个参数不适用于count_if函数。
3、全局变量我们可以将长度阈值设置成一个全局变量代码可能像这样
1 int maxLength;
2 bool LengthIsLessThan(const string str) {
3 return str.length()maxLength;
4 }
5 int rescount_if(vec.begiin(), vec.end(), LengthIsLessThan);这段代码看似很不错实则不符合规范刚重要的是它不优雅。原因有以下几点要考虑
1、容易出错为什么这么说呢我们必须先初始化maxLength的值才能继续接下来的工作如果我们忘了则可能无法得到正确答案。此外变量maxLength和函数LengthIsLessThan之间是没有必然联系的编译器无法确定在调用该函数前是否将变量初始化给码农平添负担。
2、没有可扩展性如果我们每遇到一个类似的问题就新建一个全局变量尤其是多人合作写代码时很容易引起命名空间污染namespace polution的问题当范围域内有多个变量时我们用到的可能不是我们想要的那个。
3、全局变量的问题每当新建一个全局变量即使是为了coding的便利我们也要知道我们应该尽可能的少使用全局变量因为它的cost很高而且可能暗示你这里有一些待解决的优化方案。说了这么多还是要回到我们原始的那个问题有什么解决方案呢答案当然就是这篇blog的正题部分仿函数。我们的初衷是想设计一个unary function使其能做binary function的工作这看起来并不容易但是仿函数能解决这个问题。先来看仿函数的通俗定义仿函数functor又称为函数对象function object是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样不过作为仿函数的类都必须重载operator()运算符举个例子
1 class Func{
2 public:
3 void operator() (const string str) const {
4 coutstrendl;
5 }
6 };1 Func myFunc;
2 myFunc(helloworld!);helloworld!仿函数其实是上述解决方案中的第四种方案成员变量。成员函数可以很自然的访问成员变量1 class StringAppend{2 public:3 explicit StringAppend(const string str) : ss(str){}4 5 void operator() (const string str) const{6 coutstr ssendl;7 }8 9 private:
10 const string ss;
11 };
12
13 StringAppend myFunc(is world);
14 myFunc(hello);hellois world我相信这个例子能让你体会到一点点仿函数的作用了它既能想普通函数一样传入给定数量的参数还能存储或者处理更多我们需要的有用信息。让我们回到count_if的问题中去是不是觉得问题变得豁然开朗了
1 class ShorterThan {
2 public:
3 explicit ShorterThan(int maxLength) : length(maxLength) {}
4 bool operator() (const string str) const {
5 return str.length() length;
6 }
7 private:
8 const int length;
9 };1 count_if(myVector.begin(), myVector.end(), ShorterThan(length));//直接调用即可这里需要注意的是不要纠结于语法问题ShorterThan(length)似乎并没有调用operator()函数其实它调用了创建了一个临时对象。你也可以自己加一些输出语句看一看。这篇博文就先记到这里了仿函数也在STL中大量涉及到不彻底弄懂仿函数的问题看到STL源码就会一头包。后续可能再分享一些关于functor的资料和个人学习心得。