C++11Lambda表达式捕获变量(Capturing the Variable)与本地变量(Local Variable)

在Lambda的方括号[]中命名局部变量称为捕获变量(capturing the variable)。如果没有在**方括号[]**指定变量,则在Lambda表达中不能使用。Lambda捕获变量默认是值传递方式。
如下面代码:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

using namespace std;

int main(int argc, char** argv)
{
    // 初始化向量
    vector<int> data{1,2,3,4,5,6,7,8,9};
    int times = 3;

    // 输出原始数据
    // 输出
    cout << "before transform:\n";
    copy(data.begin(),data.end(),ostream_iterator<int>(cout,","));
    cout << endl;

    // 定义表达
    auto op_times = [times](int i){return i * times;};
    transform(data.begin(),data.end(),data.begin(),op_times);

    // 输出
    cout << "after transform times=" << times << endl;
    copy(data.begin(),data.end(),ostream_iterator<int>(cout,","));
    cout << endl;

    // 改变本地变量
    times = 5;
    transform(data.begin(),data.end(),data.begin(),op_times);
    
    // 输出
    cout << "after transform times=" << times << endl;
    copy(data.begin(),data.end(),ostream_iterator<int>(cout,","));
    cout << endl;
    
    return 0;
}

程序输出:
在这里插入图片描述
当本地变量times的值从3改变为5后,调用transform函数输出的结果不是每个元素乘以5。相当于transform函数调用了两次。为了实现调用结果随着本地变量times的改变而改变,需要通过引用方式捕获变量。

auto op_times = [&times](int i){return i * times;};

在这里插入图片描述
程序运行结果达到预期!

Lambda表达式捕获变量后,被捕获的变量能够在Lambda表达式中改变吗?看看下面的代码:

#include <iostream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

using namespace std;

int main(int argc, char** argv)
{
    int x{0};
    auto test_func = [x](int y){
        // 改变参数的值
        x = 1;
        y = 2;
        return x + y;
    };
    int local{0};
    cout <<"after call test_func:"<< test_func(local) <<",x = " << x <<",local=" << local << endl;
    return 0;
}

编译的结果如下:
在这里插入图片描述
这说明在值传递方式捕获变量的情况,在Lambda表达式中是不能修改的!

猜你喜欢

转载自blog.csdn.net/wujuxKkoolerter/article/details/114101943