Skip to content

C++:Lambda

Syntax

Lambda-syntax.png

Explanation

mutable
allows body to modify the parameters captured by copy, and to call their non-const member functions.

How to use

람다의 사용법은 아래와 같다.

  • []{}
  • [](인자){}
  • [](인자)->반환값{}
  • [](인자)->반환값{}
  • [](인자)mutable ->반환값{}
  • [](인자)mutable throw() ->반환값{}
  • [](인자)mutable ->반환값{}(): 직접 호출.

각각의 명칭은 아래와 같다.

  • []: 람다 소개자 (Lambda Introducer)
  • (): 파라미터 지정자 (Parameter Specifier)
  • {}: 람다 몸체 (Lambda Body)

List of caputre

  • []: 아무것도 캡처하지 않음
  • [&x]: x만 Capture by reference
  • [x]: x만 Capture by value
  • [&]: 모든 외부 변수를 Capture by reference
  • [=]: 모든 외부 변수를 Capture by value
  • [x,y]: x,y 를 Capture by value
  • [&x,y]: x는 Capture by reference , y는 Capture by value
  • [&x, &y]: x,y 를 Capture by reference
  • [&, y]: y 를 제외한 모든 값을 Capture by reference
  • [=, x]: x 를 제외한 모든 값을 Capture by value

Tip

std::function<T> to c-style function pointer

결론부터 말하자면 불가능하다.

The result of std::bind is a complicated C++ object. It has to store all the bound arguments,
for example. So it is most definitely not convertible to a pointer to function.

The callback specification you're dealing with apparently doesn't allow a "user data" payload,
so there's nowhere to hide a pointer to a C++ object which you could use to invoke a non-static member funtion.
This means you will have to call a global or static member function,
or resort to a global/static member/per-thread variable to store the object pointer.

Troubleshooting

Function parameter

아래와 같이 함수 인자로 function객체를 전달하여 Lambda 내부에서 호출할 경우 정상적으로 호출되지 않는 현상이 발생할 수 있다.

using accept_handle = std::function<void(error_code const &, Session *)>;
// ...
void accept(accept_handle handler, Session * new_session) {
    _acceptor.async_accept(new_session->getSocket(), [&](error_code const & error) {
        handler(error, new_session);
    });
}

이 경우 Lambda의 All Reference Capture([&])를 사용하면 안된다. 이렇게 되면 함수의 종료시 스택 리와인드와 함께 accept_handle handler인자도 사라지기 때문이다. 이런 경우엔 아래와 같이 직접 변수로 전달하도록 사용해야 한다.

using accept_handle = std::function<void(error_code const &, Session *)>;
// ...
void accept(accept_handle handler, Session * new_session) {
    _acceptor.async_accept(new_session->getSocket(), [handler, new_session](error_code const & error) {
        handler(error, new_session);
    });
}

Favorite site

References


  1. Programming_IT_-_C++_Lambda_function.pdf 

  2. Vallista's_Development_Lap-C++11-Lambda_Expression_and_Functor.pdf 

  3. Amateur_Game_Programmer_FromPt-Lambda.pdf 

  4. ProjectK-C++0x-Lambda.pdf