C++ Lambda函数的用处

July 20th, 2013 by JasonLe's Tech Leave a reply »

C++11终于知道要在语言中加入匿名函数了。匿名函数在很多时候可以为编码提供便利,这在下文会提到。很多语言中的匿名函数,如C++,都是用Lambda表达式实现的。Lambda表达式又称为lambda函数。我在下文中称之为Lambda函数。

Lambda函数的用处

假设你设计了一个地址簿的类。现在你要提供函数查询这个地址簿,可能根据姓名查询,可能根据地址查询,还有可能两者结合。要是你为这些情况都写个函数,那么你一定就跪了。所以你应该提供一个接口,能方便地让用户自定义自己的查询方式。在这里可以使用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;
};

 

从上面代码可以看到,findMatchingAddressses函数提供的参数是Func类型,这是一个泛型类型。在使用过程中应该传入一个函数,然后分别对地址簿中每一个entry执行这个函数,如果返回值为真那么表明这个entry符合使用者的筛选要求,那么就应该放入结果当中。那么这个Func类型的参数如何传入呢?

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; }
);
}

 

 

Lambda函数和STL

lambda函数的引入为STL的使用提供了极大的方便。比如下面这个例子,当你想便利一个vector的时候,原来你得这么写:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
//…
for ( auto itr = v.begin(), end = v.end(); itr != end; itr++ )
{
cout << *itr;
}

现在有了lambda函数你就可以这么写

#include<algorithm>

vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
//…
for_each( v.begin(), v.end(), [] (int val)
{
cout << val;
} );

而且这么写了之后执行效率反而提高了。因为编译器有可能使用”循环展开“来加速执行过程(计算机系统结构课程中学的)。