C++ 之 lambda

本文详细介绍了C++中匿名函数的使用,重点讨论了如何通过[]、[=]、&、[&,foo]等不同方式捕获外部变量,以及[this]捕获this指针的应用实例。
摘要由CSDN通过智能技术生成

#include <iostream>

using namespace std;

#if 0

/*
 * 创建一个匿名函数并执行。Objective-C采用的是上尖号^,而C++ 11采用的是配对的方括号[]
 */
#include <iostream>
using namespace std;
 
int main()
{
    []{
        cout << "Hello,Worldn";
    }();
}

/*
 * 我们也可以方便的将这个创建的匿名函数赋值出来调用:
 */
int main()
{
    int i = 1024;
    auto func = [](int i) { // (int i) 是指传入改匿名函数的参数
        cout << i;
    };
    func(i);
}

/*
 * 捕获选项
 */

[] Capture nothing (or, a scorched earth strategy?)        // 什么都不捕获
[&] Capture any referenced variable by reference        // 通过引用捕获任何引用的变量
[=] Capture any referenced variable by making a copy    // 通过制作副本来捕获任何引用的变量
[=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference // 通过复制捕获任何引用的变量,但通过引用捕获变量foo
[bar] Capture bar by making a copy; don’t copy anything else    // 通过复制捕获栏; 不要复制任何其他内容
[this] Capture the this pointer of the enclosing class            // 捕获封闭类的this指针


/**********************************
 * [] 不捕获任何变量
 **********************************/
int main()
{
    int i = 1024;
    auto func = [] { cout << i; };
    func();
}
/*
vs 报错
error C3493: 无法隐式捕获“i”,因为尚未指定默认捕获模式
error C2064: 项不会计算为接受 0 个参数的函数

g++ 报错:
error: ‘i’ is not captured

要直接沿用外部的变量需要在 [] 中指名捕获。
*/


/**********************************
 * [=] 拷贝捕获
 **********************************/
int main()
{
    int i = 1024;
    auto func = [=]{  // [=] 表明将外部的所有变量拷贝一份到该函数内部
        cout << i;
    };
    func();
}
// 结果:1024

int main()
{
    int i = 1024;
    auto fun1 = [=]{
        // fun1 内存在 i
        cout << i; // 1024
        auto fun2 = []{ // 未指名捕获, i 不存在
            cout << i;
        };
        fun2();
    };
    fun1();
}

/**********************************
 * [&] 引用捕获
 **********************************/
int main()
{
    int i = 1024;
    cout << &i << endl;
    auto fun1 = [&]{
        cout << &i << endl;
    };
    fun1();
}
// 结果:
// 0x28ff0c
// 0x28ff0c


/**********************************
 * [=, &] 拷贝与引用混合
 **********************************/
int main()
{
    int i = 1024, j = 2048;
 
    cout << "i:" << &i << endl;
    cout << "j:" << &j << endl;
 
    auto fun1 = [=, &i]{ // 默认拷贝外部所有变量,但引用变量 i
        cout << "i:" << &i << endl;
        cout << "j:" << &j << endl;
    };
    fun1();
}

//结果
//outside i:0x28ff0c
//outside j:0x28ff08
//inside i:0x28ff0c
//inside j:0x28ff04

/**********************************
 * [bar] 指定引用或拷贝
 **********************************/
int main()
{
    int i = 1024, j = 2048;
 
    cout << "outside i value:" << i << " addr:" << &i << endl;
 
    auto fun1 = [i]{
        cout << "inside  i value:" << i << " addr:" << &i << endl;
        // cout << j << endl; // j 未捕获
    };
    fun1();
}

//结果:
//outside i value:1024 addr:0x28ff08
//inside i value:1024 addr:0x28ff04


int main()
{
    int i = 1024, j = 2048;
 
    cout << "outside i value:" << i << " addr:" << &i << endl;
 
    auto fun1 = [&i]{
        cout << "inside  i value:" << i << " addr:" << &i << endl;
        // cout << j << endl; // j 未捕获
    };
    fun1();
}
//outside i value:1024 addr:0x28ff08
//inside i value:1024 addr:0x28ff08

int main()
{
    int i = 1024, j = 2048, k;
 
    cout << "outside i:" << &i << endl;
    cout << "outside j:" << &j << endl;
 
    auto fun1 = [i, &j]{
        cout << "inside  i:" << &i << endl;
        cout << "inside  j:" << &j << endl;
        // cout << k; // k 未捕获
    };
    fun1();
}
//outside i:0x28ff0c
//outside j:0x28ff08
//inside i:0x28ff00
//inside j:0x28ff08


#endif


/**********************************
 * [this] 捕获 this 指针
 **********************************/
class test
{
public:
    void hello() {
        cout << "test hello!\n";
    };

    void lambda() {
        auto fun = [this]{ // 捕获了 this 指针
            this->hello(); // 这里 this 调用的就是 class test 的对象了
        };
        fun();
    }
};
 
int main()
{
    test t;
    t.lambda();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值