基于C++ Lambda表达式的程序优化分享

—-想了解基于C++ Lambda表达式的程序优化分享的全部内容且更多的C语言教程关注<计算机技术网(www.ctvol.com)!!>

什么是Lambda?

C++ 11加入了一个非常重要的特性——Lambda表达式。营里(戴维营)的兄弟都对Objective-C很熟悉,许多人多block情有独钟,将各种回调函数、代理通通都用它来实现。甚至有人选择用FBKVOController、BlocksKit等开源框架将KVO、控件事件处理都改为通过block解决。原因就是简单、方便、直观,函数的定义和使用出现在同一个地方。这里的Lambda表达式实际上和block非常类似,当然如果你用它和Swift语言的闭包比较,那就是一回事了。

这是一个关于CC++程序员的一个小故事,关于C++11——刚刚通过的新标准的一个小故事…

请不要误会,题目中所提及的“优化”并不是提升程序的性能——Lambda表达式干不了这个。从本质上来说,它只是一种“语法糖”而已。不使用这种表达式,我们照样可以写出满足需求的程序。正如放弃C而使用汇编,或者放弃汇编而使用机器语言一样,你能控制的范围就在那里,不增不减。但如果有得选择,我相信大部分人会选择汇编而非机器语言,选择C而非汇编,甚至选择C++而非C语言……。如果你确实是这样选择的,那么我有理由相信,你会选择C++新标准中的Lambda表达式,因为它确实能够简化你的程序,让你写起程序来更容易;让你的程序更易读,更优美;同时也让你有更多向同行炫耀的资本。

从一个实际的应用说起

让我们还是看一个例子吧。

无论是C语言的使用者,还是C++的用户,如果你从事PC程序的算法开发,我有96.57%的把握认为你可能使用过C++标准模板库STL(其中的string,vector之类)。毕竟,STL的抽象不错,不用白不用,是不是。STL中有一大类是算法,这些算法的抽象同样不错,我们就拿排序算法(sort)来说事吧。

假设现在有一个结构称为Student,其中包含了ID与name两项——分别表示学号与姓名。在某个应用中,用户希望对一个Student的数组按照ID的从大到小排序,那么程序可能写成如下的形式(基于C++ Lambda表达式的程序优化分享中的所有程序均在Visual Studio 2010下编译通过):

  #include <string>  #include <vector>  #include <iostream>  #include <iterator>  #include <algorithm>  using namespace std;  struct Student {  unsigned ID;  string name;  Student(unsigned i, string n) : ID(i), name(n){}  };  struct compareID {  bool operator ()(const Student& val1, const Student& val2)  const {  return val1.ID < val2.ID;  }  };  int main(int argc, char* argv[]) {  Student a[] = {Student(2, “John”), Student(0, “Tom”), Student(1, “Lily”)};  sort(a, a+3, compareID());  for(int i=0; i<3; ++i)  cout<<a[i].ID<<' ‘<<a[i].name<<endl;  return 0  }

程序用sort进行排序,之后用一个for循环输出结果。而之所以能完成这个排序,则是由于仿函数compardID的存在。

现在假设用户的需求变了(或者是另一个需求),需要你按照学生的姓名进行排序,那么你需要重新写一个仿函数如下:

  struct compareName {  bool operator ()(const Student& val1, const Student& val2) const {  return val1.name < val2.name;  }  };

然后将sort的调用修改为:

  sort(a, a+3, compareName());

问题出现了,你意识到了吗?你只是想表达一个很简单的排序方式,确不得不引入很多的代码行来建相应的仿函数。如果这个函数在很多地方都会用到,那么建立它的价值还相对较大。如果只是用在一个地方,你也不得不中段你流畅是思路,一边骂娘一边写出这么多行代码。另一方面,程序的读者在读到相应部分的时候,也不得不中段他流畅的思路,在工程的某个地方苦苦求索——compareName或者compareID是怎么干的呢?

是的,是的,作为一个C++老鸟,你会说,这样写代码太不专业了。完全可以有不建立仿函数的写法,比如以ID排序时,完全可以通过引入boost库中的bind来实现,比如这样:

  sort(a, a+3, bind(less<unsigned>(), bind(&Student::ID, _1), bind(&Student::ID, _2)));

如果你能写出或是读懂这段代码,我承认你的C++水平确实说得过去(如果读不懂,没关系,它不是基于C++ Lambda表达式的程序优化分享的重点)。但这段代码真的好吗?确实,这样可以省略了仿函数。但问题是代码的复杂性大大增加了——即使如此简单的一个需求,bind表达式也要复杂如斯,更复杂一点的需求要写成何等复杂的形式啊,这对于bind本身,写程序的人,读程序的人都是一种折磨——你hold住吗?

如果用Lambda表达式呢,唔,这个sort语句可以这么写:

  sort(a, a+3, [](const Student& val1, const Student& val2){ return val1.ID < val2.ID; });

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/487829.html

(0)
上一篇 2020年11月12日
下一篇 2020年11月12日

精彩推荐