@iStarLee
2019-10-02T09:26:03.000000Z
字数 2768
阅读 489
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 lambda
template<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 matches
if ( 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 work
processor.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则不这样做。如果您正在处理的代码会发生很大变化,并且包含在许多源文件中,那么这将非常有用。