C++lambda表达式的基本使用方法

186 阅读2分钟

lambda表达式的基本使用方法

基本结构

[]()mutable->int
{
    return 1;
}
  1. capture 子句 (C++ 规范中也称为 lambda 引入器 。)
  2. 参数列表 选。 (也称为 lambda 声明符)
  3. 可变规范 选。
  4. exception-specification 选。
  5. trailing-return-type 选。
  6. lambda 正文

Capture 子句

[] {};//不访问变量
[=] {};//按值捕获
[&] {};//通过引用捕获

显式声明

int a, b;
//引用捕获a,值铺货b
[a] {};
[&a, b] {};
[b, &a] {};
[&, b] {};
[=, &a] {};

类中

void S::f(int i) 
{
    [&, i]{};      // OK
    [&, &i]{};     // ERROR: i preceded by & when & is the default
    [=, this]{};   // ERROR: this when = is the default
    [=, *this]{ }; // OK: captures this by value. See below.
    [i, i]{};      // ERROR: i repeated
}

后跟省略号的捕获是包扩展,如此 可变模板 示例所示:

template<class... Args>
void f(Args... args) 
{
    auto x = [args...] { return g(args...); };
    x();
}

//移动捕获

auto ptr = make_unique<int>(1);
//...
auto a = [ptr = move(ptr)]()
{
// use ptr
};

参数列表

C++14 中,如果参数类型为泛型,则可以使用 auto 关键字作为类型说明符。 此关键字告知编译器创建函数调用运算符作为模板。 参数列表中的每个实例 auto 都等效于不同的类型参数。

auto y = [] (auto first, auto second)
{
    return first + second;
};[&, n](int a,int b) mutable
{
    m = ++n + a;
}(3,1);//执行表达式

可变参数

template<class... Args>
void f(Args... args)
{
    auto x = [args...]{ return g(args...); };
    x();
}

Lambda 正文

lambda 表达式的 lambda 主体是复合语句。 它可以包含普通函数或成员函数正文中允许的任何内容。 普通函数和 lambda 表达式的主体均可访问以下变量类型:

  • 从封闭范围捕获变量,如前所述。
  • 参数。
  • 本地声明的变量。
  • 类数据成员在类内声明并 this 捕获时。
  • 具有静态存储持续时间的任何变量,例如全局变量

可变规范

通常,lambda 的函数调用运算符是常量值,但使用 mutable 关键字会取消此操作。它不生成可变数据成员。 该 mutable 规范使 lambda 表达式的正文能够修改值捕获的变量。

int m = 0;
int n = 0;
//规范 mutable 允许 n 在 lambda 中修改
[&, n](int a) mutable { m = ++n + a; }(4);

作为参数

生成器

vector<int> v;
static int nextValue = 1;
// The lambda expression that appears in the following call to
// the generate function modifies and uses the local static
// variable nextValue.
generate(v.begin(), v.end(), [] { return nextValue++; });
//WARNING: this isn't thread-safe and is shown for illustration only

for_each

int evenCount = 0;
for_each(v.begin(), v.end(),
         [&evenCount](int n)
         {
             cout << n;
             if (n % 2 == 0) {
                 cout << " is even " << endl;
                 ++evenCount;
             }
             else {
                 cout << " is odd " << endl;
             }
         });

find_if

const list<int>::const_iterator result =
find_if(numbers.begin(), numbers.end(), [](int n) { return (n % 2) == 0; });

constexpr

//constexpr lambda 表达式或将其用于常量表达式。
int y = 32;
auto answer = [y]() constexpr
{
    int x = 10;
    return y + x;
};
​
//如果 lambda 结果满足函数的要求constexpr,则 lambda 是constexpr隐式的:
auto answer = [](int n)
{
    return 32 + n;
};
​
constexpr int response = answer(10);
​
//如果 lambda 是隐式或显式 constexpr的,并且你将其转换为函数指针,则生成的函数也是 constexpr:
auto Increment = [](int n)
{
    return n + 1;
};
​
constexpr int(*inc)(int) = Increment;

\