람다 표현식: 짧은 동작을 함수처럼 전달하기
10강. 람다 표현식: 짧은 동작을 함수처럼 전달하기
이번 강의에서 해결할 문제
한 번만 사용하는 정렬 조건 때문에 파일 전역 함수를 계속 만들면 규칙과 사용 위치가 멀어집니다. 반대로 람다가 주변 변수를 무분별하게 참조하면 언제 어떤 값이 사용되는지 알기 어렵고 수명 오류가 생길 수 있습니다.
학습 목표
- 람다의 매개변수, 본문, 반환값을 읽습니다.
- 값 캡처와 참조 캡처의 차이를 설명합니다.
- 정렬과 조건 계산에 작은 람다를 전달합니다.
먼저 알아야 할 핵심 개념
람다는 호출 가능한 익명 함수 객체를 만드는 표현입니다. []는 캡처 목록, ()는 매개변수, {}는 실행 본문입니다. [threshold]는 현재 값을 복사하고 [&threshold]는 원본을 참조합니다. 람다가 오래 보관된다면 참조 대상 수명이 끝나지 않는지 반드시 확인해야 합니다.
가장 작은 실행 가능한 예제
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> enemyHealth{80, 25, 50};
const int dangerLimit{50};
std::sort(enemyHealth.begin(), enemyHealth.end(),
[](const int left, const int right) { return left < right; });
const auto dangerous = std::count_if(
enemyHealth.begin(), enemyHealth.end(),
[dangerLimit](const int health) { return health >= dangerLimit; });
std::cout << enemyHealth.front() << ' ' << dangerous << '\n';
}
핵심 코드 줄별 설명
- 정렬 람다는 왼쪽 값이 더 작을 때
true를 반환합니다. - 이 람다는 외부 값이 필요 없어 캡처 목록이 비어 있습니다.
- 필터 람다는
dangerLimit을 값으로 복사해 사용합니다. count_if는 조건이 참인 원소 수를 반환합니다.- 정렬 뒤
front()는 가장 작은 체력 25입니다.
실행 결과와 값 변화
25 2
위험 기준을 70으로 바꾸면 80만 조건을 만족해 두 번째 값은 1이 됩니다. 값 캡처이므로 람다가 만들어질 때의 기준이 사용됩니다.
단계별 실습
실습 목표
아이템 가격을 내림차순 정렬하고 예산 이하 개수를 셉니다.
시작 전 상태와 실행 방법
vector<int> prices{120, 40, 300}과 예산 150을 준비합니다.
1단계: 최소 코드 작성
두 값을 비교하는 람다로 가격을 내림차순 정렬합니다.
2단계: 값 또는 조건을 바꿔 결과 비교
예산을 100과 200으로 바꾸며 count_if 결과를 비교합니다.
3단계: 작은 기능 확장
아이템 구조체의 가격 멤버를 기준으로 정렬하도록 람다 매개변수를 바꿉니다.
4단계: 스스로 해결하기
이름 길이가 짧은 아이템을 먼저 정렬하되 길이가 같으면 이름순으로 정렬하세요.
막혔을 때
외부 변수를 사용했는데 캡처되지 않았다는 오류가 나면 필요한 값만 [budget]처럼 명시합니다. [&]로 모두 참조하면 편하지만 수명과 수정 범위가 숨으므로 학습 단계에서는 피합니다.
흔한 실수와 해결 방법
- 비교 함수가 일관되지 않음: 같을 때 항상 false가 되도록 엄격한 비교를 작성합니다.
- 모든 값을
[=]또는[&]로 캡처: 실제 사용하는 이름만 적어 의존성을 보이게 합니다. - 지역 변수를 참조한 람다를 오래 저장: 값 캡처나 더 긴 수명 구조로 바꿉니다.
게임 개발 연결
거리순 타깃 정렬, 조건에 맞는 아이템 필터, UI 버튼 콜백에 람다를 사용할 수 있습니다. 비동기 작업이나 다음 프레임까지 보관되는 콜백은 캡처 객체 수명을 특히 주의해야 합니다.
이해 점검 질문 3개
- 람다의 캡처 목록은 무엇을 표현하나요?
- 값 캡처와 참조 캡처는 이후 원본 변경을 어떻게 다르게 보나요?
- 정렬 비교 람다가 같은 두 값에 true를 반환하면 왜 문제가 되나요?
핵심 요약
람다는 짧은 지역 규칙을 사용 위치 가까이에 둡니다. 캡처는 의존성과 수명을 뜻하므로 필요한 값만 명시하고, 오래 저장되는 콜백은 참조 수명을 검토합니다.
다음 강의 연결
11강. override·final·default·delete에서 클래스의 상속·생성·복사 의도를 컴파일러가 검사할 수 있게 표시합니다.
람다 표현식: 짧은 동작을 함수처럼 전달하기 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.