C++ lambda 用法

  1. 为什么要使用lambda

    + 就地匿名的定义一个目标函数或者函数对象,不需要额外的再写一个命名函数或者函数对象,以更直接的方式去写函数,可以调高程序的可读性和可维护性。

    + 简洁:不要额外的的再写一个函数或者函数对象,避免了代码膨胀或者功能分散。

    + 在需要的时间或者地点实现功能闭包,是程序更加灵活。

  2. lambda 的语法

    + [capture] (parameters) mutable->return-type{statement};

    3. lambda 的内部实现

    + 编译器会自动生成一个匿名类,该类重载了 () 运算符。

int id = 0;
    auto f = [id]() mutable {
        cout << "id: " << id << endl;
        ++id;
    };
  • 当写出上面一块代码时,那么编译器就会将他们转换成以下的代码
class Functor {
private:
    int id;
public:
    void operator() (){
        std::cout << "id: " << id << endl;
        ++id;
    }
};
  • 其中,函数名具体是取决于编译器自己编译,私有成员变量是捕获列表所来,重载的 () 操作符函数具体是由 lambda 表达式 body 所来

  • lambda 的使用

    1. 捕获列表:

    + []:什么也不捕获

    + [=]: 按值的方式捕获所有变量

    + [&]: 按引用方式捕获所有变量

    + [boo]:值捕获 boo 的值

    + [=, &a]: 按值捕获所有局部变量,按引用捕获变量a。

    + [=, &a, &b, &c]:同上,

    + [&, a]:按引用捕获所有局部变量,按值捕获方式捕获 a

    + [&, a, b, c]:同上

    + [this]:在成员函数中,直接捕获 this 指针

    2. mutable:

    + 值捕获后,在匿名函数中对该值是不能做修改的,如果想要做修改,必须加上 mutable 关键字,并且在匿名函数中做的修改结果在函数外是不会生效的;

    3. parameters:

    + 参数列表也是可以将外部的值传递给匿名函数内部的,和捕获列表的在于,parameter 对应的 operator函数的形参列表。

    4. return-tyep:

    + 对于编译器能自动推导的返回类型,可以省略 return-type,但是如果无法推导的类型,就必须添加上返回类型

    + 当函数不止一个return语句时,就需要加上返回类型了。

  • 总结:

    1. 捕获列表中,捕捉的值会作为类的私有成员生成,且是const类型,所以值捕获的数值无法在匿名函数中修改,引用捕获可以修改,且这种改变可以传到外部。

Example:

#include<iostream>

using namespace std;

void capturePassedByValueAll();
void capturePassedByReferenceAll();
void capturePassedByValueExceptSome();
void lambdaMutable();
void lambdaParameter();
void lambdaReturnType();

int main() {

    // passed by value
    capturePassedByValueAll();

    // passed by reference
    capturePassedByReferenceAll();

    // passed by value all excpet some
    capturePassedByValueExceptSome();

    // passed by value all and mutable
    lambdaMutable();

    // lambda in parameter
    lambdaParameter();

    // lambda in return
    lambdaReturnType();


    return 0;
}

void lambdaReturnType()
{  
    auto autoGetRetutnType = []() {
        return 5+3;
    };
    cout  << "lambdaReturnType = " << autoGetRetutnType() << endl;

    auto specifyReturnType = [](int x)->string {
        if (x > 0) {
            return "x more than zero";
        }
        else {
            return "x less than zero";
        }
    };
    cout  << "specifyReturnType = " << specifyReturnType(2) << endl;

}

void lambdaParameter()
{
    int a = 1;
    int b = 2;

    auto f = [](int a, int b) {
        return a > b ? a : b;
    };

    cout  << "lambdaParameter f(a,b) = " << f(a, b) << endl;
}

void lambdaMutable()
{
    int a = 1;
    int b = 2;

    auto passedByValueMutable = [=]()mutable {
        cout << "lambdaMutable start a :" << a << " b: " << b << endl;
        a++;
        b++;
        cout << "modify after a :" << a << " b: " << b << endl;
    };
    passedByValueMutable();
    cout << "lambdaMutable a :" << a << " b: " << b << endl;
}

void capturePassedByValueExceptSome()
{
    int a = 0;
    int b = 1;
    int c = 100;
    int d = 200;
    auto passedByValueExceptSome = [=, &c, &d]() {
        cout << "capturePassedByValueExceptSome start a = " << a << " b = " << b << endl;
        cout << "midify after c = " << c << " d = " << d << endl;

        c++;
        d++;
        cout << "midify after c = " << c << " d = " << d << endl;
        cout << "capturePassedByValueExceptSome end" << endl;

    };

    passedByValueExceptSome();
    cout << "a = " << a << " b = " << b << endl;    
}

void capturePassedByReferenceAll()
{
    int c = 100;
    int d = 200;
    auto passedByReference = [&] {
        cout << "passedByReference c = " << c << " d = " << d << endl;
        c++;
        d++;
        cout << "c = " << c << " d = " << d << endl;
        cout << "passedByReference end" << endl;
    };
    passedByReference();
    cout << "c = " << c << " d = " << d << endl;
}

void capturePassedByValueAll()
{
    int a = 0;
    int b = 1;
    auto passedByValue = [=]() {
        cout << "passedByValue start a = " << a << " b = " << b << endl;
        cout << "passedByValue end" << endl;
    };

    passedByValue();
    cout << "a = " << a << " b = " << b << endl;
}

原文链接: https://www.cnblogs.com/wanghao-boke/p/15836627.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/187507

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 上午11:18
下一篇 2023年2月12日 上午11:18

相关推荐