Lambda Expression in C++

Lambda表达式是编程中很实用的工具,作为热门的,最受欢迎编程语言之一(大概?),C++11及其以后版本,也提供了对lambda表达式的支持,下面让我们逐步学习和了解C++中的Lambda表达式吧

首先我们先看一个lambda表达式的使用例子:

#include <algorithm>

void sort_by_abs(int *arr, int len){
  // use C++ lambda as param of the sort function
  std::sort(arr, arr+len, [](int a, int b){
    return (std::abs(a) < std::abs(b));
  });
}

观察得到,C++ lambda表达式基本结构如下:

[=]() mutable throw() -> type {
  // lambda body
  return ret_value;
}

接下来我们将逐个部份进行介绍。

Capture Clause

首先是第一部份[]。这一部份被称之为捕获语句(Capture Clause)。在这一部份,你可以捕获lambda声明时范围内的变量。你可以在周围环境中捕获需要的变量,同时可以选择捕获类型为值传递还是引用传递。

默认情况下,Capture语句中捕获的变量将会以值传递形式传递。

void func1()
{
    int num, num2;
    auto a = [num]() {};     // pass value
    auto b = [&num]() {};    // pass reference
    auto c = [&, num]() {};  // (default: reference) pass reference
    auto d = [=, &num]() {}; // (default: value) pass reference
}

需要注意,配置默认捕获模式将会将周围环境的所有变量暴露给lambda表达式。如上述代码,lambda c和d均设置了默认Capture设置,这种情况下,周围环境的所有变量都将会被Capture,c和d可以各自依照自己设定好的默认捕获模式访问到num2,但是a和b不能访问到num2

同时,lambda表达式初始化时,也允许进行赋值操作,请看下面的代码。

void func()
{
    int a, b, c = 0;
    auto lambda = [a, b, &refToC = c]() mutable
    {
        refToC++;
        cout << refToC << endl; // expected: 1
    };
    lambda();
    cout << c << endl; // expected: 1
}
// output:
// 1
// 1

如上述代码,我们可以在lambda表达式的 Capture Clause 部分声明新的变量。新的声明变量同样可以是值传递或者引用传递。需要注意的是,在 Capture Clause 声明变量时,我们无需显式指定变量类型,lambda表达式会自动推断其类型(如上述代码中,refToC自动被推断为 int & 类型)

还有一个需要注意的点,默认情况下,Capture Clause 中捕获和声明的所有变量将会以const形式进行传递。也就是说lambda body中,默认不可以对 Capture Clause 中的变量进行更改。如果您想在 lambda body 中对 Capture Clause 中的值或者引用进行更新或修改,请在参数列表,函数体前加上mutable关键字。

Published by Oyasumi

Just a normal person in the world

2 thoughts on “Lambda Expression in C++

Leave a Reply

Your email address will not be published. Required fields are marked *