[C++] 람다(lambda) 표현식, 장단점

SunowMin·2023년 12월 9일
0

C++

목록 보기
1/8

람다는 C++11에서 도입된 문법으로, 일반적인 함수와 다른 점은 이름과 소속(클래스)이 명시되지 않은 익명함수

람다식 또는 람다함수라고 부름



1. 일반함수, 람다함수 비교


아래 코드는 동일한 동작을 하는 함수를 '일반 함수'와 '람다 함수'로 작성한 것

#include<iostream>
#include<string>
using namespace std;

// 일반 함수 정의
void sum1(int a, int b)
{
	cout << "sum1 func : " << a + b << end;
}

int main(void) {
	// 일반 함수 호출
    sum1(10, 20);
    
    // 람다 함수
    [](int a, int b)
    {
    	cout << "sum2 lambda : " << a + b << endl;
    }(30, 40);
    
    return 0;
}

실행결과
sum1 func : 30
sum2 lambda : 70


일반 함수 구조

반환형 함수이름 (매개변수)
{
// 구현몸체
}

람다 함수 구조

[](int a, int b){ cout << "" << endl;}(30,40);




2. 람다식 구문 형태


[캡처](매개변수)->Return Type {구현몸체}(호출인자)

소괄호()는 생략 가능

[캡처]

  • 외부에 있는 데이터를 가져다 사용하기 위한 요소로 변수, 상수 등이 해당됨
  • 보통 참조 유형을 많이 사용하지만 복사 방식도 사용됨
    - 참조는 캡처하고 있는 변수의 주소가 넘어가기 때문에 람다 몸체에서 수정이 되면 원본에 적용됨
    • 복사 방식은 값이 복사되어 사용되기에 원본에 적용되지 않음

(매개변수)

  • 함수의 매개변수와 같음
  • 함수에서 사용할 인수 목록

->Return Type

  • 람다식에서 반환하고자 하는 반환 자료형

{구현 몸체}

  • 함수의 구현부

(호출인자)

  • 함수 호출시 인자




3. 람다식 예


다음은 람다를 이용하여 함수 객체를 생성하고 실행한 내용

캡처와 매개변수 없을 때

void LambdaFunc()
{
	// 함수 객체 생성
    auto lamdaFunc = []()->void {
    		cout << "Lambda test" << endl;
	};  
    
    // 함수 객체 실행
    lamdaFunc();
}

실행결과
Lambda test

  • 캡처는 없기 때문에 참조할 어떤 변수도 없음
  • 함수의 매개변수와 반환값도 사용하지 않아서 ->void로 작성
  • 몸체에는 cout을 이용하여 문자열 출력

캡처와 매개변수 있을 때

void LambdaFunc()
{
	int32 sum = 10;
    
	// 함수 객체 생성
    auto lamdaFunc = [&sum](int number)->void {
    		sum += number;
    };
            
    // 함수 객체 실행
    lamdaFunc(20);
    cout << "sum : " << sum << endl;
}

실행결과
sum : 30

  • 정수형 sum 변수 선언하고, sum을 람다 구문의 캡처로 사용
  • 람다식 안에서 sum의 값이 변형될 수 있도록 참조 형태로 넘겨줌
  • 매개변수는 함수와 같은 방식으로 선언
  • 몸체에서 참조로 넘어온 sum의 값을 변경




4. 장단점

장점

  • 간결한 문법
    : 간단한 작업이나 짧은 함수를 정의할 때 간결한 문법을 제공

단점

  • 가독성 저하
    : 복잡한 로직이나 긴 함수를 표현하기에는 람다식은 오히려 가독성을 떨어뜨릴 수 있음
  • 캡처된 변수의 생명 주기 관리
    : 람다식에서 외부 변수를 캡처할 경우, 캡처된 변수의 생명 주기와 관련된 문제가 발생할 수 있음 (예, 람다식이 캡처한 변수가 이미 소멸된 상태에서 람다가 호출되면 문제 발생)
  • 디버깅 어려움
    : 람다식을 사용할 때 디버깅을 위한 식별자가 부재하므로, 코드 추적에 어려울 수 있음

0개의 댓글