@iStarLee
2019-10-02T01:26:03.000000Z
字数 2768
阅读 705
cpp
lambda是cpp11加进去的特性。有时叫closures或者匿名函数。类似 functor和function pointer。
有时候是一个小的功能函数,直接在语句里面定义的话,会使得代码非常简单
#include <iostream>using namespace std;int main(){auto func = [] () { cout << "Hello world"; };func(); // now call the function}
某个查询的功能函数可能有可以根据很多个条件查询,如果给每一种查询都设计一个函数,会非常繁杂,不如直接传入一个Func,让用户自定义查询方式
假设你设计了一个地址簿的类。现在你要提供函数查询这个地址簿,可能根据姓名查询,可能根据地址查询,还有可能两者结合。要是你为这些情况都写个函数,那么你一定就跪了。所以你应该提供一个接口,能方便地让用户自定义自己的查询方式。在这里可以使用lambda函数来实现这个功能。
#include <string>#include <vector>class AddressBook{public:// using a template allows us to ignore the differences between functors, function pointers// and lambdatemplate<typename Func>std::vector<std::string> findMatchingAddresses (Func func){std::vector<std::string> results;for ( auto itr = _addresses.begin(), end = _addresses.end(); itr != end; ++itr ){// call the function passed into findMatchingAddresses and see if it matchesif ( func( *itr ) ){results.push_back( *itr );}}return results;}private:std::vector<std::string> _addresses;};
// 用户使用// 如果用户要使用不同的方式查询的话,只要定义不同的lambda函数就可以了。AddressBook global_address_book;vector<string> findAddressesFromOrgs (){return global_address_book.findMatchingAddresses(// we're declaring a lambda here; the [] signals the start[] (const string& addr) { return addr.find( ".org" ) != string::npos; });}
// 遍历vector<int> v;v.push_back( 1 );v.push_back( 2 );//...for_each( v.begin(), v.end(), [] (int val){cout << val;} );
现在有这样一个任务,统计最长的消息长度
// 消息接受,处理函数设置#include <functional>#include <string>class EmailProcessor{public:void receiveMessage (const std::string& message){if ( _handler_func ){_handler_func( message );}// other processing}void setHandlerFunc (std::function<void (const std::string&)> handler_func){_handler_func = handler_func;}private:std::function<void (const std::string&)> _handler_func;};
// 消息存储,大小比较#include <string>class MessageSizeStore{public:MessageSizeStore () : _max_size( 0 ) {}void checkMessage (const std::string& message ){const int size = message.length();if ( size > _max_size ){_max_size = size;}}int getSize (){return _max_size;}private:int _max_size;};
使用的时候,It's COOL!!!
EmailProcessor processor;MessageSizeStore size_store;// processor.setHandlerFunc(size_store.checkMessage); // this won't workprocessor.setHandlerFunc([&size_store](const std::string &msg){size_store.checkMessage(msg);});processor.receiveMessage("I");processor.receiveMessage("love");processor.receiveMessage("hahahahah");std::cout<<size_store.getSize(); //9

std::function
虽然有时候你并不需要知道lambda函数类型,因为传入的时候你可以使用函数模板,定义变量的时候可以用auto自动推导,但是使用函数模板就必须将函数定义在头文件中。
与模板相比,std::function的一大优点是,如果编写模板,需要将整个函数放在头文件中,而std::function则不这样做。如果您正在处理的代码会发生很大变化,并且包含在许多源文件中,那么这将非常有用。