상세 컨텐츠

본문 제목

C++ 람다 Lambda 함수와 Capture 구문

프로그래밍

by 경밤 2021. 7. 10. 07:55

본문

반응형

캡처의 개념

캡처의 역할은 본문에서 사용하는 외부 변수에 대해 그 사용 방식을 변수명에 묵시적으로 정하거나 새 이름으로 명명하여 명시적으로 사용 방식을 정하는 것 이다.

캡처의 작동은, 실행이 아닌 오직 캡처 선언문에서 지정한 것들이 캡처 선언문 내에서만 바로 쓰여짐에 따라 실행되어지는 순서에 관계 없이 그 람다 선언과 동시에 캡처 선언문 내 외부 변수 값이 산술 연산 또는 대입이 된다.

람다의 사용

C++에서 람다를 사용할때 Capture 구문을 맨 앞, 그 뒤 매개변수, 마지막으로 화살표와 함께 반환 타입을 명시 해주면 된다.

auto f = []()->void {};

이러한 캡처 구문은 아래 2개 정도로 나눠 볼 수 있다.

auto callByValue = [=]()->void {};

auto callByRefer = [&]()->void {};

[]를 캡처 구문 선언문 본문이라고 할 수 있겠고, 그 안의 내용은 =와 &로 구분한다. 이때 이것들의 차이는 중괄호 내 에서 쓰이는 모든 외부 변수들에 관해 어떤 형식으로 불러오는지의 것 이다.

명시적으로 어떤 변수를 사용할지, 이것은 참조로, 이것은 값으로써 캡처하는지는 아래와 같이 할 수 있다.

int n = 1, m = 2;
auto l = [&r = n, v = m]() -> int {
    r = 10;
    return r * v;
};
cout << "n, m : (" << n << ", " << m << ")" << endl;
cout << "l() : " << l() << endl;
cout << "n, m : (" << n << ", " << m << ")" << endl;

m은 l의 선언과 동시에 v에 저장되어 v=2가 된다. 이때, l을 호출하기 전 아무리 m을 바꿔도 v의 값은 l을 선언할때의 m의 값과 다를바가 없다. 그러나, r은 n의 주소를 캡처했기 때문에, 값을 바꾸면 그 값도 변하게 된다.

예시

#include <iostream>
using namespace std;

int main() {
    int a = 10;
    auto f = [&]() {
        a = 20;
    };
    auto f2 = [=]() {
        return a;
    };

    auto foo = [=]() -> int {
        return a + 10;
    };
    cout << "Result of Foo()" << foo() << endl;
    
    auto bar = [](int a) -> int {
        return a + 10;
    };
    cout << "Result of Bar()" << bar(a) << endl;

    return 0;
}
반응형

관련글 더보기