Lambda Expression Details

Original link: https://ifmet.cn/posts/9ece64cc/

Brief Description: Explain the basic usage, principles, and usage scenarios of Lambda expressions in detail.

202203241724748.png

[TOC]

This article was originally published on ” Xie Zang’s Small Station “, and is reproduced here simultaneously.

Lambda expressions

grammar

[captures](params) mutable exception -> ret {body}

• Capture table columns, capturing variables in the current scope, separated by commas

• parameter list

• The optional qualifier, optional, mutable allows changing captured-by-value variables within the body of the function

• exception specifier, optional, noexcept

• Return value type, optional, in most cases can be automatically deduced by the compiler

• Function body

capture list

  • [var] Capture by value, copy var to Lambda scope by value, cannot be modified by default

  • [&var] capture by reference, captures the reference of var into the lambda scope

  • [=] captures the value of all variables in its scope

  • [&] captures references to all variables in the scope

  • [this] In the member function of the class, capture the current this pointer


Initialize capture

Initialization capture: C++14 support, when capturing variables, you can

• Specify the name of the data member in the closure class

• Direct capture of the result of an expression

202203241729927.png


principle

• Lambda expressions:

​Rvalue expression, which is part of the source code, instructs the compiler to generate the corresponding closure class and closure object

• Closure class:

​Generated by the compiler at compile time based on Lambda expressions, each Lambda expression has a corresponding unique closure class

• Closure:

​The closure class instance created at runtime, the call to the Lambda expression is to call the member function of this instance

202203241756896.svg

Divided into闭包类– 捕获变量and闭包类– 不捕获变量;


Lambda expression usage scenarios

• Create variables to store lambda expressions

• Lambda expressions as function parameters

• Lambda expressions as class data members

• Using containers to store lambda expressions

Defining Lambda Expression Variables with auto and decltype

 auto f = [ y ] ( int x ) { return x * y ; } ; //右值初始化auto f2 = f ; //拷贝decltype ( f ) f3 = std :: move ( f ) ; //移动auto && f4 = [ y ] ( int x ) { return x * y ; } ; //右值引用绑定右值const auto & f5 = f4 ; //常量左值绑定

Parameterizing Lambda Expression Types Using Templates

 template < typename F > void fn1 ( F fn ) { fn ( ) ; } template < typename F > void fn2 ( F && fn ) { fn ( std :: forward < F > ( fn ) ) ; }  

std::function function object wrapper

  • Can wrap any type of function object

  • Objects with the same function signature can be stored as the same type

     std :: function < float ( float , float ) > fn ; fn = std :: fmaxf ; //普通函数fn = std :: multiplies < float > ( ) ; //仿函数fn = [ x ] ( float a , float b ) { return a * b ; } ; // Lambda 

performance issues

  • Dynamically allocate memory

  • virtual function call

pointer

  • Dangling references

     auto make_lambda ( int i ) { return [ & ] ( int v ) { return v + i ; } ; } auto l = make_lambda ( 10 ) ; l ( 20 ) ; 
  • hanging pointer

     void Object :: f ( int i ) { std :: thread ( [ = ] { print ( i + m_value ) ; } ) . detach ( ) ; }

This article is reprinted from: https://ifmet.cn/posts/9ece64cc/
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment