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;
    }
  • 相关阅读:
    洛谷 P1226 【模板】快速幂||取余运算 题解
    洛谷 P2678 跳石头 题解
    洛谷 P2615 神奇的幻方 题解
    洛谷 P1083 借教室 题解
    洛谷 P1076 寻宝 题解
    洛谷 UVA10298 Power Strings 题解
    洛谷 P3375 【模板】KMP字符串匹配 题解
    Kafka Shell基本命令
    Mybatis与Hibernate的详细对比
    MyBatis简介
  • 原文地址:https://www.cnblogs.com/LuckCoder/p/8668125.html
Copyright © 2011-2022 走看看