Skip to content

Lambda expressions

发展概述

C++11

引入 Lambda functions and expressions ,参见:

1) Wikipedia C++11#Lambda functions and expressions

2) cppreference C++11 # variadic templates

C++14

新增 generic lambda 特性,参见:

1) cppreference C++14 # generic lambdas

2) Wikipedia C++14 # Generic lambdas

新增 lambda init-capture/Lambda capture expressions,参见:

1) cppreference C++14 # lambda init-capture

2) Wikipedia C++14 # Lambda capture expressions

C++17

新增 lambda capture of *this 特性,参见:

1) cppreference C++17 # lambda capture of *this

新增 constexpr lambda 特性,参见:

1) cppreference C++17 # constexpr lambda

microsoft Lambda Expressions in C++

NOTE: 这篇讲解地非常好

Parts of a Lambda Expression

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <iostream>

void abssort(float* x, unsigned n)
{
    std::sort(x, x + n,
            // Lambda expression begins
            [](float a, float b)
            {
                return (std::abs(a) < std::abs(b));
            } // end of lambda expression
            );
}

int main()
{
    float Array[] = { 6, -5, 4, -3, 2, 1 };

    std::cout << "Before sort:" << std::endl;
    for (auto Element : Array)
    {
        std::cout << Element << std::endl;
    }
    std::size_t Len = sizeof(Array) / sizeof(float);
    std::cout << "After sort:" << std::endl;
    abssort(Array, Len);
    for (auto Element : Array)
    {
        std::cout << Element << std::endl;
    }
}

This illustration shows the parts of a lambda:

  1. capture clause (Also known as the lambda-introducer in the C++ specification.)
  2. parameter list Optional. (Also known as the lambda declarator)
  3. mutable specification Optional.
  4. exception-specification Optional.
  5. trailing-return-type Optional.
  6. lambda body.

Capture Clause

cppreference Lambda expressions

Passing Lambda Expressions with std::function

在drdobbs Lambdas in C++11中有如下描述:

Each time you are creating a lambda expression, its implementation creates a new class under the hood. Thus, each lambda creates a separate class and has a different type. As you might guess, even when many lambda expressions receive the same arguments and return the same type, each of them will be a different class; that is, a different type. Luckily, C++11 incorporates a wrapper for any of the following functions with std::function and makes it easy to pass around lambda expressions:

NOTE: std::function是一个abstraction

  • Lambda expression
  • Function pointer
  • Functor

关于此的例子,参见C++\Language-reference\Functions\std-utility-lib-Function-objects\cppreference-std-function.md

Capture by reference

#include <iostream>

int main(void)
{
    int i = 0;
    std::cout << &i << std::endl;
    auto F = [&i]()
    {

        std::cout<<&i<<std::endl;
    };
    F();
}
// g++ test.cpp -pedantic -Wall -Wextra --std=c++11

从输出来看,两者的地址相等,也就是是同一个object,因此是capture by reference。