[C++] Lambda(람다)

빵욱·2024년 8월 19일

Lambda? 람다?

람다(lambda) 표현식은 익명 함수를 간결하게 작성할 수 있는 문법입니다. C++11부터 도입되었으며, 함수 객체나 짧은 콜백 함수를 작성할 때 매우 유용합니다.

C#으로 개발을할 때 많이 활용 했었는데 c++을 쓰게되면서 생각나서 정리해본다.
현재 프로젝트엔 람다가 써진 부분이 없던데 나중에 잘 활용하겠지...

표현식

Lambda 람다
[](파라미터){함수 동작 코드}(호출 인자)

[capture](parameters) -> return_type {
// 함수 내용
};

[] 부분을 캡처라고 한다.

[capture]: 람다 내부에서 사용할 외부 변수들을 캡처하는 방식.

[ ] : 아무것도 캡처하지 않음.
[=] : 외부 변수들을 값으로 캡처.
[&] : 외부 변수들을 참조로 캡처.
[x] : 변수 x를 값으로 캡처.
[&x] : 변수 x를 참조로 캡처.

이렇게 사용될 수 있다.

-> return_type (선택 사항): 반환 타입을 명시적으로 지정할 수 있다.
         보통 반환 타입을 생략해도 컴파일러가 추론

예제

일반 적인 람다 사용.

 // 참조가 없는 일반 람다 함수.
 auto add = [](int a, int b) {
     return a + b;
     };

 //람다 함수 바로 실행.
 [](int a, int b) ->void
 {
         std::cout << a + b << std::endl;
 }(30, 40);
 // ->void 이 리턴 타입은 명시 안해도 컴파일러가 추론한다고 함.

값 캡처

// 값 캡처 람다.
int x = 10;
auto add_x = [x](int a) {
    return a + x;
    };

값 캡처는 변수의 복사본을 람다 함수 내부에서 사용한다.
람다 내부에서 수정해도 원래 변수에는 영향을 주지 않는다.
근데 복사한 변수에는 대입이나 ++ 같은 연산자가 적용되지 않는다.
상수처럼 취급되기 때문에 변경이 불가능하다.

참조 캡처

 // 참조 캡처 람다.
 auto Increment_x = [&x]()
     {
         x++;
     };

 auto refLamda_ex = [&x](int a)
     {
         x++;
         return x * a;
     };

참조 캡처에서는 값 변경이 가능하고 원본 데이터에 영향을 준다.

혼합 사용

 // 값 캡처, 참조 캡처 같이 사용 가능.
 int x = 10;
 int y = 20;
 auto mix_capture = [x, &y]() {
     // x는 값으로 캡처, y는 참조로 캡처
     y = x + y;
     };

mutable 키워드를 사용한 람다

mutable 키워드를 사용하면 값 캡처 변수의 값을 변경할 수 있다고 한다.

이 변경 사항은 원래 변수에는 영향을 미치지 않으며, 오직 람다 내부에서만 적용된다.

auto mutableLambda = [x]() mutable {
    x++;
    std::cout << "x in lambda: " << x << std::endl;
    };
mutableLambda();  // 출력: x in lambda: 11
std::cout << "original x: " << x << std::endl;  // 출력: original x: 10



mutable과 캡처 목록 혼합

// mutable과 캡처 목록 혼합
auto mixMutableLambda = [x, &y]() mutable {
    x++;  // x는 값으로 캡처되었기 때문에 복사본만 증가
    y++;  // y는 참조로 캡처되었기 때문에 원래 y가 증가

    std::cout << "x in lambda: " << x << std::endl;
    std::cout << "y in lambda: " << y << std::endl;

    };

mixMutableLambda();  // 출력: x in lambda: 11, y in lambda: 21
std::cout << "original x: " << x << std::endl;  // 출력: original x: 10
std::cout << "original y: " << y << std::endl;  // 출력: original y: 21
profile
rove drink eat

0개의 댓글