[C++] 람다 식(Lambda Expression)
카테고리: Cpp
태그: Lambda
이 글은 C++의 람다 식(Lambda Expression)을 공부하고 정리한 글입니다.
람다 식은 이름이 없는 함수 개체이다.
람다 식
- 이름이 없는 함수 개체
-
내포(nested)되는 함수
구조
[<captures>](<parameters>) <specifiers> -> <return_type> { <body> }
캡처 블록(captures)
- 람다 식을 품는 범위(scope) 안에 있는 변수를 람다 식에 넘겨줄 때 사용
- 캡처의 종류
- []
- 비어 있음. 캡처하지 않음
- =
- 값에 의한 캡처. 모든 외부 변수를 캡처함
- 람다 식 안에서 수정할 수 없음
- &
- 참조에 의한 캡처. 모든 외부 변수를 캡처함
-
<변수 이름="">
변수>
- 특정 변수를 값으로 캡처
- 람다 식 안에서 수정할 수 없음
- &<변수 이름="">
변수>
- 특정 변수를 참조로 캡처
- []
매개변수 목록(parameters)
- 선택 사항
- 빈 괄호를 생략할 수 있음
지정자(specifiers)
- 선택 사항
- mutable
- 값에 의해 캡처된 개체를 수정할 수 있게 함
반환 형(return_type)
- 선택 사항
- 반환 형을 적지 않으면 반환문을 통해 유추해줌
코드 예시
// 방법 1 auto noCapture = []() { std::cout << "No capturing example 1" << std::endl; }; noCapture(); // 방법 2. 바로 실행 [] { std::cout << "No capturing example 2" << std::endl; }(); float score1 = 80.f; float score2 = 20.f; auto max1 = []() { return score1 > score2 ? score1 : score2; }; // 컴파일 에러 auto max2 = [=]() { return score1 > score2 ? score1 : score2; }; // OK auto changeValue1 = [=]() { score1 = 100.f; // 컴파일 에러. score1을 수정할 수 없음 }; auto changeValue2 = [&]() { score1 = 100.f; // OK }; auto printValue1 = [score1] { std::cout << score1 << " / " << score2 << std::endl; // 컴파일 에러. score2에 접근할 수 없음 }; auto printValue2 = [score1, score2] { std::cout << score1 << " / " << score2 << std::endl; // OK }; auto changeValue3 = [=, &score1] { score1 = 100.f; // 참조에 의한 캡처 std::cout << score2 << std::endl; // 값에 의한 캡처 }; auto add = [](int a, int b) { return a + b; }; std::cout << add(score1, score2) << std::endl; auto foo = [score1]() { std::cout << ++score1 << std::endl; // 컴파일 에러. score1을 수정할 수 없음 } auto foo = [score1]() mutable { std::cout << ++score1 << std::endl; // OK }
람다 식의 장점
- 간단한 함수를 빠르게 작성할 수 있음
auto max = [](float a, float b) { return a > b ? a : b; };
람다 식의 단점
- 함수 재사용성이 낮음
- 사람들은 보통 함수를 새로 만들기 전에 클래스에 있는 기존 함수를 찾아 봄
- 람다 함수는 눈에 잘 띄지 않아서 못 찾을 가능성이 높음
- 그럼 코드 중복이 발생
베스트 프랙티스
- 기본적으로, 이름 있는 함수를 쓰자(전통적 방식)
- 자잘한 함수는 람다로 써도 괜찮음(한 줄짜리 함수)
- 허나 재사용할 수 있는 함수를 찾기 좀 어려움
- 정렬 함수 처럼 STL 컨테이너에 매개변수로 전달할 함수들도 좋은 후보
참조
💻 열심히 공부해서 작성 중이니 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 알려주시면 감사하겠습니다! 😸
댓글 남기기