C++自学篇 lamda表达式

前言

参考链接:
链接: C++ Lambda表达式详解
链接: 一文深入了解C++ lambda(C++17)

本篇使用的编译与运行命令为

g++ -std=gnu++2b test.cpp -o test.exe
./test.exe

标准lamda表达式:

[capture list] (parameter list) specifiers exception -> type { function body }

capture list是捕获列表,在应用中填。
parameter list是参数列表,在应用中填。
specifiers是限定符,在应用中填。
exception是异常说明符,在应用中填。
-> type是返回值类型,在应用中填。
function body是表达式的函数体,在应用中填。

探究lamda表达式的捕获列表

从下面2块代码的运行结果,可得出下面结论:
1.值捕获与引用捕获的使用区别

捕获列表说明
[]不使用捕获
[=]值捕获:捕获lamda表达式定义时的数据
[&]引用捕获:捕获使用lamda表达式时的数据
[this]捕获当前对象的指针,本质是引用捕获
[*this]捕获当前对象的副本,本质是值捕获
[=, &a]混合捕获:默认都使用值捕获,只有变量a使用引用捕获
[&, a]混合捕获:默认都使用引用捕获,只有变量a使用值捕获

2.lamda表达式出现嵌套时,主要关注当前的lamda表达式使用值捕获还是引用捕获
3.[this]和[*this]的区别

操作[this][*this]
调用类内的函数可以不可以
修改类内的变量可以不可以
查看this指针与获取类内的变量可以可以
this指针指向的地址无变化有变化
#include <iostream>

int main(int argc, char *argv[])
{
    int a, b, c;

    a = 10, b = 20, c = 30;
    auto fun1 = [a, b]() -> int { // 变量a/b 以"值捕获"方式传入到表达式中
        return a + b; // a == 10, b == 20
    };

    a = 110, b = 120, c = 130;
    auto fun2 = [=]() -> int { // 将所有变量 以"值捕获"方式传入到表达式中
        return fun1() + c; // fun1 == (10 + 20) = 30, c == 130
    };

    a = 210, b = 220, c = 230;
    auto fun3 = [&a, fun1] -> int { // 变量a 以"引用捕获"方式传入到表达式中
        a++; // a的值以调用时的值为准,即 a == 310,再进行 a++ 操作后,a == 411
        return fun1();
    };

    a = 310, b = 320, c = 330;
    auto fun4 = [&] -> int { // 将所有变量 以"引用捕获"方式传入到表达式中
        a++; // a的值以调用时的值为准,即 a == 411,再进行 a++ 操作后,a == 412
        b++; // b的值以调用时的值为准,即 b == 420,再进行 b++ 操作后,b == 421
        return fun1() + c; // c的值以调用时的值为准,即 c == 430
    };

    a = 410, b = 420, c = 430;
    auto fun5 = [=] -> int { // 将所有变量 以"值捕获"方式传入到表达式中
        return fun4(); // fun4由于用"引用捕获",此时的a/b/c的值以fun5调用时为准,即 a == 412,b == 421,c == 430
    };

    int result1 = fun1(); // fun1内的变量a/b对应10/20,fun1 == 30
    std::cout << "Running fun1: " << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
    std::cout << "result1: " << result1 << std::endl;

    int result2 = fun2(); // fun2内的fun1/c对应30/130,fun2 == 160
    std::cout << "Running fun2: " << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
    std::cout << "result2: " << result2 << std::endl;

    int result3 = fun3(); // fun3内的fun1对应30,fun3 == 30
    std::cout << "Running fun3: " << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
    std::cout << "result3: " << result3 << std::endl;

    int result4 = fun4(); // fun4内的fun1/c对应30/430,fun4 == 460
    std::cout << "Running fun4: " << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
    std::cout << "result4: " << result4 << std::endl;

    int result5 = fun5(); // fun5内的fun4对应460,fun5 == 460
    std::cout << "Running fun5: " << "a = " << a << ", b = " << b << ", c = " << c << std::endl;
    std::cout << "result5: " << result5 << std::endl;

    return 0;
}

运行结果:

Running fun1: a = 410, b = 420, c = 430
result1: 30
Running fun2: a = 410, b = 420, c = 430
result2: 160
Running fun3: a = 411, b = 420, c = 430
result3: 30
Running fun4: a = 412, b = 421, c = 430
result4: 460
Running fun5: a = 413, b = 422, c = 430
result5: 460
#include <iostream>
#include <functional>

class TestLamda {
public:
    TestLamda() {}
    ~TestLamda() {}

    void run();

    void runTest1(std::string name) { std::cout << __func__ << ": " << name << std::endl; }
    void runTest2(std::string name) { std::cout << __func__ << ": " << name << std::endl; }

private:
    int m_runCnt;
};

void TestLamda::run()
{
    typedef std::function<void(void)> TestFunc;
    m_runCnt = 10;

    TestFunc testFunc1 = [this](void) {
        this->runTest1("1");
        this->m_runCnt += 1;
        std::cout << "testFunc1 "  << this << ": "  << this->m_runCnt << std::endl;
    };

    TestFunc testFunc2 = [*this](void) {
        // *this->runTest2("1");
        // this->m_runCnt = 0;
        std::cout << "testFunc2 " << this << ": "  << this->m_runCnt << std::endl;
    };

    m_runCnt = 1000;

    std::cout << "run " << this << ": "  << this->m_runCnt << std::endl;

    testFunc1();
    std::cout << "run " << this << ": "  << this->m_runCnt << std::endl;

    testFunc2();
    std::cout << "run " << this << ": "  << this->m_runCnt << std::endl;
}

int main(int argc, char *argv[])
{
    TestLamda testInstance;
    testInstance.run();
    return 0;
}

运行结果:

run 0xeed5ff8ec: 1000
runTest1: 1
testFunc1 0xeed5ff8ec: 1001
run 0xeed5ff8ec: 1001
testFunc2 0x13b20581730: 10
run 0xeed5ff8ec: 1001
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值