## 람다식의 구조
람다식은 보통 이런 형태로 생겼습니다.
[캡처](매개변수) -> 반환타입 { 함수 본문 };
- [ ] (캡처 절, Capture Clause): 람다의 가장 큰 특징입니다. 람다 함수 바깥에 있는 변수를 안으로 "붙잡아와서" 사용할 수 있게 해주는 통로입니다.
- [ ]: 아무것도 캡처하지 않음
- [=]: 바깥의 모든 변수를 **값(복사)**으로 캡처
- [&]: 바깥의 모든 변수를 참조로 캡처
- [var]: var라는 변수만 값으로 캡처
- [&var]: var라는 변수만 참조로 캡처
- () (매개변수, Parameter List): 일반 함수처럼 매개변수를 받는 곳입니다. 필요 없으면 생략 가능합니다.
- -> 반환타입 (Return Type): 함수의 반환 타입을 명시하는 부분인데, 대부분 컴파일러가 알아서 추론해주기 때문에 생략 가능한 경우가 많습니다.
- {} (함수 본문, Function Body): 실제 코드가 들어가는 부분입니다.
## 그래서 언제 사용할까요? (예시)
람다식은 특히 sort 같은 표준 라이브러리 알고리즘 함수와 함께 사용할 때 매우 유용합니다.
예시 1: std::sort와 함께 사용하기
아까 보았던 내림차순 정렬을 람다식으로 바꿔보겠습니다.
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9};
// 별도의 비교 함수나 greater<>() 없이
// 세 번째 인자로 비교 로직을 담은 람다식을 바로 작성!
std::sort(vec.begin(), vec.end(), [](int a, int b) {
return a > b; // a가 b보다 크면 true -> 내림차순
});
for (int num : vec) {
std::cout << num << " "; // 결과: 9 5 4 3 1 1
}
std::cout << std::endl;
return 0;
}
별도의 비교 함수를 만들 필요 없이 sort가 필요한 그 줄에서 바로 정렬 로직을 작성할 수 있어 코드가 훨씬 간결해집니다.
예시 2: 캡처 기능 활용하기
벡터의 모든 원소를 더하는 코드를 람다식으로 작성해 보겠습니다.
#include <iostream>
#include <vector>
#include <numeric> // for_each
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
int sum = 0;
// for_each는 각 원소에 대해 주어진 함수(람다)를 실행
// [&sum]을 통해 바깥의 sum 변수를 참조로 가져와 값을 직접 더함
std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
sum += n;
});
std::cout << "합계: " << sum << std::endl; // 결과: 합계: 15
return 0;
}
[&sum]을 통해 람다 함수 바깥에 있는 sum 변수에 접근해서 값을 수정하는 것이 핵심입니다.
캡처 자세한 예시
## 1. []: 아무것도 캡처하지 않음
가장 기본적인 형태로, 람다 함수는 바깥의 어떤 변수에도 접근할 수 없습니다. 오직 람다 함수 내부에서 정의된 변수나 매개변수만 사용할 수 있습니다.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int value = 10;
string message = "Hello";
// value나 message에 접근하려고 하면 컴파일 에러 발생
auto myFunction = []() {
// cout << value << endl; // ERROR: 'value' is not captured
cout << "I can't see outside variables." << endl;
};
myFunction();
return 0;
}
핵심: 외부와 완전히 단절된, 독립적인 함수를 만들 때 사용합니다.
## 2. [=]: 값으로 캡처 (Capture by Value)
람다가 생성되는 시점에 바깥 변수들의 값을 복사해서 가져옵니다. 따라서 람다 내부에서는 복사된 값을 사용하며, 바깥의 원본 변수에는 영향을 주지 못합니다.
#include <iostream>
using namespace std;
int main() {
int apples = 10;
// 람다 생성 시점의 apples(10)가 복사되어 람다 안에 저장됨
auto countApples = [=]() {
// 람다 안의 apples는 복사본이므로, 여기서 값을 바꿔도
// 바깥의 apples는 변하지 않음
// apples = 20; // ERROR: 값으로 캡처한 변수는 수정 불가
cout << "Inside lambda, I have " << apples << " apples." << endl;
};
apples = 20; // 람다를 만든 후 원본 값을 변경
cout << "Outside, I now have " << apples << " apples." << endl;
// 람다 실행
countApples(); // 결과: Inside lambda, I have 10 apples.
return 0;
}
핵심: 람다를 만들 때의 **"스냅샷"**을 찍는 것과 같습니다. 람다 생성 이후에 원본 값이 바뀌어도 람다 안의 값은 그대로입니다.
## 3. [&]: 참조로 캡처 (Capture by Reference)
바깥 변수의 **"별명" 또는 "바로가기"**를 가져오는 것과 같습니다. 람다 내부에서 변수를 사용하면 실제 원본 변수에 접근하게 됩니다. 따라서 람다 안에서 값을 바꾸면 원본도 바뀝니다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int totalSum = 0;
vector<int> numbers = {1, 2, 3, 4, 5};
// [&]를 사용해 바깥의 totalSum에 직접 접근
for_each(numbers.begin(), numbers.end(), [&](int num) {
// 여기서 totalSum을 수정하면 바깥의 원본이 바뀜
totalSum += num;
});
cout << "Total sum is: " << totalSum << endl; // 결과: Total sum is: 15
return 0;
}
핵심: 람다를 통해 외부 변수를 직접 제어하고 싶을 때 사용합니다. 마치 리모컨으로 TV를 조작하는 것과 같습니다.
## 4. 특정 변수만 지정해서 캡처하기
전체를 캡처하는 [=]나 [&] 대신, 필요한 변수만 콕 집어서 캡처할 수도 있습니다.
- [var]: var만 값으로 캡처
- [&var]: var만 참조로 캡처
- [=, &var]: 기본적으로 값으로 캡처하지만, var만은 참조로 캡처
- [&, var]: 기본적으로 참조로 캡처하지만, var만은 값으로 캡처
#include <iostream>
using namespace std;
int main() {
int x = 100;
int y = 200;
// x는 값으로, y는 참조로 캡처
auto selectiveCapture = [x, &y]() {
// x = 101; // ERROR: x는 값으로 캡처되어 수정 불가
cout << "x (by value): " << x << endl;
y = 201; // OK: y는 참조로 캡처되어 수정 가능
cout << "y (by reference): " << y << endl;
};
selectiveCapture();
cout << "After lambda, original y is now: " << y << endl; // 결과: 201
return 0;
}
핵심: 꼭 필요한 변수만, 필요한 방식으로 가져와서 코드의 의도를 명확하게 하고 실수를 줄일 수 있습니다.
## 핵심 요약
- 람다식은 이름 없는 임시 함수다.
- 필요한 곳에서 즉시 생성하여 사용하고 사라진다.
- 코드를 간결하고 가독성 있게 만들어준다. (특히 알고리즘과 함께 쓸 때 👍)
- [](캡처)를 통해 외부 변수에 접근하는 강력한 기능을 가지고 있다.
'개발 공부 > 코딩 공부' 카테고리의 다른 글
| 최대 공약수, 최소 공배수 (0) | 2026.04.02 |
|---|---|
| C++ 입출력 (0) | 2025.09.15 |
| 프로그래머스 리스트 자르기 (0) | 2025.09.13 |
| c++ <limits>, const &auto (0) | 2025.09.03 |
| 복사와 함수 인자 전달 , 그리고 메모리 (0) | 2025.09.03 |