[关闭]
@iStarLee 2019-10-02T09:26:03.000000Z 字数 2768 阅读 489

lambda 函数

cpp


Reference

1 介绍

lambda是cpp11加进去的特性。有时叫closures或者匿名函数。类似 functor和function pointer。

用处1

有时候是一个小的功能函数,直接在语句里面定义的话,会使得代码非常简单

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. auto func = [] () { cout << "Hello world"; };
  6. func(); // now call the function
  7. }

用处2

某个查询的功能函数可能有可以根据很多个条件查询,如果给每一种查询都设计一个函数,会非常繁杂,不如直接传入一个Func,让用户自定义查询方式

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

  1. #include <string>
  2. #include <vector>
  3. class AddressBook
  4. {
  5. public:
  6. // using a template allows us to ignore the differences between functors, function pointers
  7. // and lambda
  8. template<typename Func>
  9. std::vector<std::string> findMatchingAddresses (Func func)
  10. {
  11. std::vector<std::string> results;
  12. for ( auto itr = _addresses.begin(), end = _addresses.end(); itr != end; ++itr )
  13. {
  14. // call the function passed into findMatchingAddresses and see if it matches
  15. if ( func( *itr ) )
  16. {
  17. results.push_back( *itr );
  18. }
  19. }
  20. return results;
  21. }
  22. private:
  23. std::vector<std::string> _addresses;
  24. };
  1. // 用户使用
  2. // 如果用户要使用不同的方式查询的话,只要定义不同的lambda函数就可以了。
  3. AddressBook global_address_book;
  4. vector<string> findAddressesFromOrgs ()
  5. {
  6. return global_address_book.findMatchingAddresses(
  7. // we're declaring a lambda here; the [] signals the start
  8. [] (const string& addr) { return addr.find( ".org" ) != string::npos; }
  9. );
  10. }

用处3: STL中很多算法的使用

  1. // 遍历
  2. vector<int> v;
  3. v.push_back( 1 );
  4. v.push_back( 2 );
  5. //...
  6. for_each( v.begin(), v.end(), [] (int val)
  7. {
  8. cout << val;
  9. } );

用处4:使用lambda创建Delegates(委托)

现在有这样一个任务,统计最长的消息长度

  1. // 消息接受,处理函数设置
  2. #include <functional>
  3. #include <string>
  4. class EmailProcessor
  5. {
  6. public:
  7. void receiveMessage (const std::string& message)
  8. {
  9. if ( _handler_func )
  10. {
  11. _handler_func( message );
  12. }
  13. // other processing
  14. }
  15. void setHandlerFunc (std::function<void (const std::string&)> handler_func)
  16. {
  17. _handler_func = handler_func;
  18. }
  19. private:
  20. std::function<void (const std::string&)> _handler_func;
  21. };
  1. // 消息存储,大小比较
  2. #include <string>
  3. class MessageSizeStore
  4. {
  5. public:
  6. MessageSizeStore () : _max_size( 0 ) {}
  7. void checkMessage (const std::string& message )
  8. {
  9. const int size = message.length();
  10. if ( size > _max_size )
  11. {
  12. _max_size = size;
  13. }
  14. }
  15. int getSize ()
  16. {
  17. return _max_size;
  18. }
  19. private:
  20. int _max_size;
  21. };

使用的时候,It's COOL!!!

  1. EmailProcessor processor;
  2. MessageSizeStore size_store;
  3. // processor.setHandlerFunc(size_store.checkMessage); // this won't work
  4. processor.setHandlerFunc([&size_store](const std::string &msg){size_store.checkMessage(msg);});
  5. processor.receiveMessage("I");
  6. processor.receiveMessage("love");
  7. processor.receiveMessage("hahahahah");
  8. std::cout<<size_store.getSize(); //9

2 语法和使用

  1. std::function

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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注