zoukankan      html  css  js  c++  java
  • C++11 lambda表达式学习

    最近在接手一个模块,看到了很多奇葩的语法,查了一下是lambda表达式,这块还真不了解。周末学习一下记录记录。

    lambda表达式是C++11最重要也最常用的一个特性之一。lambda来源于函数式编程的概念,也是现代编程语言的一个特点。目前支持lamdba的语言不少,如python,C++11, Java等。

    lambda表达式的语法归纳如下

    [ caputrue ] ( params ) opt -> ret { body; };

    1).capture是捕获列表;

    2).params是参数表;(选填)

    3).opt是函数选项;可以填mutable,exception,attribute(选填)

    mutable说明lambda表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获的对象的non-const方法。

    exception说明lambda表达式是否抛出异常以及何种异常。

    attribute用来声明属性。

    4).ret是返回值类型。(选填)

    5).body是函数体。

    捕获列表说明:lambda表达式的捕获列表精细控制了lambda表达式能够访问的外部变量,以及如何访问这些变量。

    1).[]不捕获任何变量。

    2).[&]捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。

    3).[=]捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。

    4).[=,&foo]按值捕获外部作用域中所有变量,并按引用捕获foo变量。

    5).[bar]按值捕获bar变量,同时不捕获其他变量。

    6).[this]捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者=,就默认添加此选项。捕获this的目的是可以在lamda中使用当前类的成员函数和成员变量。

    注意点:

    (1) 如果是使用按值捕获,则在定义时已经将值复制

         如果是使用按引用捕获,则在实际使用时才进行取值。 

    (2) printf函数/std::cout 的计算顺序:先从右到左压栈,然后从左到右出栈。

    测试例子:

     1 #include <iostream>
     2 
     3 int main()
     4 {
     5     int x = 1, y = 1;
     6 
     7     //不带参数, 不捕获变量
     8     auto f1 = []{std::cout<<"hello"<<std::endl;};
     9     f1();   //输出:hello
    10 
    11     //不带参数, 值传递方式捕获外部变量
    12     auto f2 = [=]() {return x + 1;};
    13     std::cout << x << " " << f2() << std::endl; //输出:1 2
    14 
    15     //带一个参数
    16     //值传递捕获y, 引用传递x    
    17     auto f3 = [&x,y](int a) mutable {x = x + a + y; ++y; return x;};
    18     std::cout << "x = " << x
    19             << ", y = " << y 
    20             << ", f3(5) = " << f3(5) << std::endl;
    21 
    22     //综合例子
    23     int a = 1, b = 1, c = 1;
    24     auto m1 = [a, &b, &c]() mutable {
    25         auto m2 = [a, b, &c]() mutable {
    26             std::cout << "m2():"<< "a = " << a
    27                     << ", b = " << b
    28                     << ", c = " << c << '
    ';
    29             a = 4; b = 4; c = 4;
    30         };
    31         a = 3; b = 3; c = 3;
    32         m2();
    33     };
    34 
    35     a = 2; b = 2; c = 2;
    36 
    37     m1();                             // 调用 m2() 并打印 123
    38     std::cout << "main():"<< "a = " << a
    39             << ", b = " << b
    40             << ", c = " << c << '
    ';
    41 
    42     return 0;
    43 }

     编译执行:

    g++ -std=c++11 test.cpp 
    
    hello
    1 2
    x = 7, y = 1, f3(5) = 7
    m2():a = 1, b = 2, c = 3
    main():a = 2, b = 3, c = 4

    参考:

    http://zh.cppreference.com/w/cpp/language/lambda

    https://blog.csdn.net/fjzpdkf/article/details/50249287

    https://blog.csdn.net/tommyzht/article/details/47334059

  • 相关阅读:
    VC++ 调用C# dll 回调函数,实现MQTT协议客户端通信
    如何正确获取ADO连接MySql的连接字符串(转载)
    SQL 操作
    MFC如何添加背景图片(转载)
    MFC CFont 要释放的资源总结
    MFC控件 Edit,控制只能输入数字和小数点
    VC MFC 获取 IP地址和MAC地址程序
    MFC CString 转 CTime
    vc mfc 写excel文件,包括数据和图表
    ADO方式操作access数据库
  • 原文地址:https://www.cnblogs.com/xudong-bupt/p/9027981.html
Copyright © 2011-2022 走看看