이 레슨과 관련된 학습 키워드
컴퓨터 과학 & 프로그래밍 — 문제 해결의 도구 → C++ 프로그래밍 — 성능과 추상화의 균형 → C++ 프로그래밍 — 성능과 추상화의 균형 → 실전
Lambda syntax, capture, std::function, closures, higher-order functions, STL integration, generic lambda.
오늘은 C++에서 Lambda가 왜 필요한지 알아보겠습니다.
Lambda는 이름 없는 함수 객체를 즉석으로 정의하는 문법입니다.
C++ 11에서 처음 도입되어 이후 버전에서 계속 강화되었습니다.
그림 상단 왼쪽을 보시면 C 스타일 함수 포인터가 나옵니다.
함수 포인터는 주변 변수를 캡처할 수가 없습니다.
상태 전달에 void 포인터가 필요해서 타입 안전성이 무너집니다.
가운데 박스를 보시면 C++ 03의 Functor 방식이 있습니다.
struct 안에 operator()를 정의하는 방법입니다.
상태 캡처는 가능하지만 보일러플레이트 코드가 너무 많습니다.
3줄짜리 로직에 클래스를 통째로 만드는 비효율이 생기죠.
오른쪽 박스를 보시면 C++ 11 Lambda가 등장합니다.
한 줄로 간결하게 쓸 수 있고 인라인 최적화도 가능합니다.
선언과 사용이 한 곳에 있으니 코드 가독성도 크게 높아집니다.
이제 Lambda 문법을 직접 해부해 보겠습니다.
그림 중간 부분을 보시면 Lambda 식 전체가 크게 표시됩니다.
맨 앞 대괄호 부분이 캡처 리스트입니다.
등호는 모든 변수를 값으로 복사하고, 앰퍼샌드는 참조 캡처입니다.
그 뒤 괄호 안은 일반 함수와 같은 매개변수 목록입니다.
화살표 다음 반환 타입은 생략할 수도 있습니다.
마지막 중괄호 안이 실제 실행될 함수 본문입니다.
캡처 모드 비교를 보면, 빈 대괄호는 캡처 없음을 뜻합니다.
혼합 캡처나 this를 이용한 멤버 접근도 지원합니다.
그림 하단을 보시면 컴파일러가 Lambda를 어떻게 변환하는지 나옵니다.
컴파일러는 Lambda를 익명 클로저 클래스로 변환합니다.
캡처된 변수는 클래스 멤버 필드가 되고, 본문은 operator() 메서드가 됩니다.
인라인 최적화 덕분에 함수 호출 오버헤드가 제로입니다.
실전에서 Lambda는 STL 알고리즘과 잘 어울립니다.
std::sort, std::find_if 등에 즉석 콜백을 넘길 수 있습니다.
C++ 14부터는 auto 매개변수로 Generic Lambda도 쓸 수 있습니다.
C++ 17의 constexpr Lambda는 컴파일 타임 계산에도 활용됩니다.