zoukankan      html  css  js  c++  java
  • C++新特性 lambda

    /*
    C++新特性:
    lambda表达式:是C++新特性最终要之一,实际上是提供了
    一个类似匿名函数的特性,而匿名函数则是在需要的一个函数
    ,但是又不想费力去命名一个函数的情况下去使用的。
    [捕获列表](参数列表)mutable(可选)异常属性->返回类型{
    //函数体
    }
    上面的语法规则除了[捕获列表]内的东西外,其他部分都很好理解,
    只是一般函数的函数名被滤去,返回值使用了->的形式进行。
    所谓捕获列表,其实可以理解为参数的一种类型,lambda表达式
    内部函数体在默认情况下是不能够使用函数体外部的变量的,
    这时候捕获列表可以起到传递外部数据的作用。根据传递的行为,
    捕获列表也分为以下几种:
    1、值捕获:与参数传值类似,值捕获的前期变量可以拷贝,不同之处
    在于,被捕获的变量在lambda表达式被创建拷贝,而非调用时候才拷贝:
    void learn_lambda_func_1(){
    int value_1 = 1;
    auto copy_value_1 = [value_1]{
    return value_1;
    } ;
    value_1 = 100;
    auto stored_value_1 = copy_value_1();
    //这时候,stored_value_1 == 1,而value_1 == 100
    //因为,copy_value_1 在创建的时候就保存了了一份value_1 的拷贝。
    我们使用auto来自动获取func的类型,这个非常重要。定义好lambda函数之后,
    就可以当这场函数来使用了。
    其中[]表示接下来开始定义lambda函数,中括号中间有可能会有参数,
    之后的()填写的是lambda函数的参数列表{}中间就是函数体了。
    lambda函数的用处:假如设计了一个地址簿的类。现在要提供函数查询
    这个地址簿,可能根据姓名查询,可能根据地址查询,还有可能两者结合
    ,要是为这些情况都写一个函数,那么很麻烦。所以我们应该提供一个接口,能方便的让用户自己定义自己的
    查询方式。
    */
    #include<iostream>
    #include <string>
    #include <vector>

    class AddressBook{
    public:
     template<typename func>
     std::vector<std::string> findMatchAddress(func a)
     {
      std::vector<str::string> resaults;
      for (auto iter = _address.begin(); iter != _address.end(); ++iter)
      {
       if (func(*iter)){
        resaults.push_back(*iter);
       }
      }
      return resaults;
     }
    private:
     std::vector<std::string>_address;
    };

    /*
    我们可以发现上面findMatchAddresses函数提供的参数是funcc类型,
    这是一个泛型类型。在使用过程中应该传入一个函数,,然后分别对
    地址簿中的每一个entry执行这个函数,如果返回值为真那么表明这个
    entry符合使用者的筛选要求,那么就应该放入结果当中,那么这个func
    类型的参数如何传入?
    */
    AddressBook gloabl_address_book;

    std::vector<std::string> findAddressesFromOrgs(){
     std::vector<std::string> a;
     [](const std::string & addr){
      return addr.find(".org") != std::string::npos;
     };
     return a;
    }

    /*
    可以看到,我们在调用函数的时候直接定义了一个lambda函数。其参数类型是:
    const string& addr
    返回值是bool类型。
    如果用户要使用不同的方式查询的话,只要定义不同的lambda函数就可以了。
    */


    void learn_lambda_func_1(){
     int value_1 = 1;

     auto func = [] {
      std::cout << "hello world" << std::endl;
     };

     func();

     auto  copy_value_1 = [value_1]
     {
      return value_1;
     };
     value_1 = 100;
     auto store_value_1 = copy_value_1();
     std::cout << store_value_1 << std::endl;
     std::cout << value_1 << std::endl;
     return;

    }

    int main(){
     learn_lambda_func_1();
     system("pause");
     std::string name;
     std::cin >> name;
     return gloabl_address_book.findMatchAddress{
      [&](const std::string& str){
       return name.find(addr) != string::npos;
      };
     }
     return 0;
    }

    /*lambda函数中的变量读取,上述列子中,
    lambda函数使用的都是函数使用的都是函数体的参数和它内部的信息,
    并没有使用外部信息。我们设想,从键盘读取一个名字,然
    后用lambda函数定义一个匿名函数,在地址簿中查找有没有
    相同名字的人。那么这个lambdaa函数势必就要能使用外部
    block中的变量,所以我们就得使用变量截取功能。
    (variable capture),从上述代码中看出,我们的lambda函数已经能使用外部作用域
    中的变量name,这个lambda函数一个最大的区别是[]中间加入了&符号,
    这就是要告诉编译器,要进行变量截取。这样lambda函数体就可以使用
    外部变量。如果不加入任何符号,编译器就不会进行变量截取。
    下面是各种变量截取的选项:
    []不截取
    [&]截取外部作用域中的所有变量,并作为引用在函数体内使用
    [=]截取外部作用域中的所有变量,并拷贝一份在函数体中使用
    [=, &foo]   截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
    [bar]   截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
    [this]            截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。
    */

    /*
    lambda函数和STL
    lambda函数的引入为STL的使用提供了极大地方便,


    using namespace std;
    v.push_back(1);
    v.push_back(2);
    //,,,
    for (auto iter = v.begin(); iter != v.end(); ++iter){
     cout << *iter << endl;
    }
    //现在有了lambda函数你可以这么写:
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    //...
    for_each(v.begin(), v.end(), [](int val)){
     cout << val << endl;
    }
    */

  • 相关阅读:
    Redis5设计与源码分析 (第17章 HyperLogLog相关命令的实现)
    Redis5设计与源码分析 (第16章 GEO相关命令)
    ES5和ES6函数的this指向
    vue响应式原理 (响应式并不等于数据双向绑定,千万不要混淆)
    vue中data为什么是函数而不是对象
    vue-enum 前端常量 枚举工具
    Vue3 写业务逻辑不适合用TS(TypeScript)
    vue-property-decorator vue3 ts 用的装饰器
    github git clone下载加速 && npm install 下载加速
    vue3 如果用ts,导出时候要用 defineComponent,这俩是配对的,为了类型的审查正确
  • 原文地址:https://www.cnblogs.com/yjds/p/8966431.html
Copyright © 2011-2022 走看看