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

    1.语法形式

    lambda表达式定义了一个匿名函数,其本质就是一个匿名的彷函数对象:

    [ 捕获表 ](参数表) 选项 -> 返回类型 { 函数体 }


    嵌入式函数

    [] (int x) ->{return x*x;};//实现了小括号运算符的类对象

    cout<< [] (int x) ->{return x*x;}(100)<<endl;//10000

    //只能写auto
    auto fun=cout<< [] (int x) ->{return x*x;};
    ||
    ||
    ||
    class <编译器生成类名>
    {
    public:
    int operator()(int x)const
    {
    return x*x;
    }
    private:
    成员变量来自捕获表;
    };

    lambda表达式的值就是《编译器生成的类名》类型的对象

    cout<<fun(100)<<endl;//10000

    cout<<fun(200)<<endl;//40000


    =========================================================

    普通函数

    int fun(int x){return x*x;}

    cout<<fun(100)<<endl;//10000

    #include <iostream>
    #include <vector>
    #include <typeinfo>
    #include <algorithm>
    using namespace std;
    void print (int x) {
        cout << x << ' ';
    }
    bool intCmp (int x, int y) {
        return x > y;
    }
    int main (void) {
        auto f1 = [] (int x = 10) -> int { return x * x; };
        /*
        class Z4mainEUliE_ {
        public:
            int operator() (int x = 10) const {
                return x * x;
            }
        };
        Z4mainEUliE_ f1;
        */
        cout << typeid (f1).name () << endl;
        cout << f1 () << ' ' << f1 (13) << ' ' << f1 (14) << endl;
        cout << [] (int x = 10) -> int { return x * x; } (15)<<endl;
    //    cout << Z4mainEUliE_ () (15) << endl;
        // 编译器可以根据return语句自动推导返
        // 回类型,因此返回类型可以省略不写
        auto f2 = [] (int x = 10) { return x * x; };
        cout << f2 (16) << endl;
        // 列表初始化不能用于返回类型的自动推导 
    //    auto f3 = [] (void) { return vector<int> {10, 20, 30}; };
    //    auto f3 = [] (void) -> vector<int> { return {10, 20, 30}; };
        // 空参数表可以省略void
    //    auto f3 = [] () -> vector<int> { return {10, 20, 30}; };
        // 空参数表且返回类型可自动推导可以省略"()"
        auto f3 = [] { return vector<int> {10, 20, 30}; };
        for (auto a : f3 ())
            cout << a << ' ';
        cout << endl;
        vector<int> vi {40, 10, 50, 20, 30};
        sort (vi.begin (), vi.end (), intCmp);
        sort (vi.begin (), vi.end (),
            [] (int x, int y) { return x > y; });
        for_each (vi.begin (), vi.end (), print);
        cout << endl;
        for_each (vi.begin (), vi.end (),
            [] (int x) { cout << x << ' '; });
        cout << endl;
        return 0;
    }

    2.捕获列表

    【】 不捕获任何外部变量

    【d】 按值捕获外部变量d

    【&d】 按引用捕获外部变量d

    【this】 捕获this指针

    【=】 按值捕获所有的外部变量,包括this指针

    【&】 按引用捕获所有的外部变量,包括this指针

    【=,&d】 按值捕获除d以外的外部变量(包括this指针),按引用捕获外部变量d

    【&,d】 按引用捕获除d以外的外部变量(包括this指针),按值捕获外部变量d


    **注意:按值捕获不可以修改变量的值,按引用捕获可以修改变量的值

    mutable :在lambda中可以修改按值捕获的外部变量,这样的lambda表达式,其参数表必须显示写出,不可省略

    3.不捕获任何外部变量的lambda表达式可以被隐式转换为函数原型相同的函数指针

    #include <cmath>
    #include <iostream>
    using namespace std;
    int a = 10;
    class Base {
    protected:
        int b = 20;
    };
    class Derived : public Base {
    public:
        void foo (int d = 40) {
            [] (int e) {
                cout << __FUNCTION__ << endl;
                cout << a << endl;
    //            cout << b << endl;
    //            cout << c << endl;
    //            cout << d << endl;
                cout << e << endl;
            } (50);
            [d] (int e) {
                cout << __FUNCTION__ << endl;
                cout << a << endl;
    //            cout << b << endl;
    //            cout << c << endl;
                cout << d << endl;
                cout << e << endl;
            } (50);
            [d,this] (int e) {
                cout << __FUNCTION__ << endl;
                cout << a << endl;
                cout << b << endl;
                cout << c << endl;
                cout << d << endl;
                cout << e << endl;
            } (50);
            [=] (int e) {
                cout << __FUNCTION__ << endl;
                cout << ++a << endl;
                cout << ++b << endl;
                cout << ++c << endl;
                cout << /*++*/d << endl;
                cout << ++e << endl;
            } (50);
            [&] (int e) {
                cout << __FUNCTION__ << endl;
                cout << ++a << endl;
                cout << ++b << endl;
                cout << ++c << endl;
                cout << ++d << endl;
                cout << ++e << endl;
            } (50);
            [=,&d] (int e) {
                cout << __FUNCTION__ << endl;
                cout << ++a << endl;
                cout << ++b << endl;
                cout << ++c << endl;
                cout << ++d << endl;
                cout << ++e << endl;
            } (50);
        }
    private:
        int c = 30;
    };
    int main (void) {
        cout << "输入两条直角边的长度:" << flush;
        int a, b;
        cin >> a >> b;
        cout << "斜边的长度:" << [] (int a, int b) {
            return sqrt (a * a + b * b); } (a, b) << endl;
        cout << "斜边的长度:" << [a, b] {
            return sqrt (a * a + b * b); } () << endl;
        /*
        class ??? {
        public:
            ??? (int& a, int& b) : a (a), b (b) {}
            int operator() (void) const {
                return sqrt (a * a + b * b);
            }
        private:
    //        int const a, b;
            int& a, b;
        };
        cout << "斜边的长度:" << ??? (a, b) () << endl;
        */
        Derived obj;
        obj.foo ();
        int x = 60;
        auto f1 = [x] { cout << x << endl; };
        ++x;
        f1 (); // 60
        int y = 70;
        auto f2 = [&y] { cout << y << endl; };
        ++y;
        f2 (); // 71
        int z = 80;
        auto f3 = [=] { cout << /*++*/z << endl; };
        auto f4 = [=] () mutable { cout << ++z << endl; };
        f4 (); // 81
        cout << z << endl; // 80
        auto f5 = [&] { cout << ++z << endl; };
        f5 (); // 81
        cout << z << endl; // 81
        auto f6 = [/*=*/] (int x, int y) -> int {
    //        cout << z << endl;
            return sqrt (x * x + y * y); };
        cout << f6 (3, 4) << endl;
        int (*pfun) (int, int) = f6;
        cout << pfun (3, 4) << endl;
        return 0;
    }
  • 相关阅读:
    Caused by: Unable to load bean: type:com.opensymphony.xwork2.ObjectFactory class:org.apache.struts2.
    走到头儿的外企之路——北漂18年(45)
    [ERROR] XML Parser Error on line 11: 注释中不允许出现字符串 "--"
    Unknown lifecycle phase "mybatis-generator-generate"
    org.eclipse.wst.xsl.jaxp.debug.invoker.TransformationException
    windows expect-5.21r1b1-setup.exe 下载链接
    linux下C语言实现静态IP地址,网关的设置
    OpenSSL “心脏滴血”漏洞
    linux 让root用户可以telnet
    perl 创建文本框
  • 原文地址:https://www.cnblogs.com/LuckCoder/p/8668125.html
Copyright © 2011-2022 走看看