람다 함수(lambda function)는 이름 없는 함수(익명 함수)로, 한 줄로 간단한 함수를 만들고 싶을 때 사용하는 문법입니다.
[capture](parameter) -> return_type {
// 함수 내용
};
#include <iostream>
int main() {
auto add = [](int a, int b) -> int {
return a + b;
};
std::cout << add(3, 4); // 출력: 7
}
auto mul = [](int x, int y) { return x * y; };
std::cout << mul(2, 5); // 10
람다 함수에서의 capture(캡처)는 람다 함수 바깥에 있는 변수들을 안으로 가져오는 방법입니다. 다시 말해, 외부 변수들을 람다 함수 안에서 사용하게 해주는 기능입니다.
[capture-list](parameter-list) { 함수 내용 }
int x = 10;
auto print = [x]() { std::cout << x << '\n'; };
print(); // 10
[=] : 외부 변수 값으로 복사[&] : 외부 변수 참조로 사용[=, &y] : 기본은 값 복사, y는 참조int x = 1, y = 2;
auto print1 = [=]() mutable {
std::cout << ++x << ", " << ++y << std::endl;
};
auto print2 = [&]() {
std::cout << x++ << ", " << y++ << std::endl;
};
→ [=] + mutable은 복사된 값을 수정 가능
→ [&]는 원본을 직접 수정
캡처(capture)가 뭔지 전혀 감이 안 온다면, 아래 진짜 쉬운 예제로 개념부터 천천히 이해해 봅시다.
외부 변수
a = 10이 있을 때,
람다 함수 안에서 이a를 더해서 출력하는 간단한 예제
[=] → 복사 캡처 (읽기만 가능)#include <iostream>
int main() {
int a = 10;
auto lambda = [=]() {
std::cout << "람다 내부: a = " << a << '\n';
};
lambda(); // 출력: 람다 내부: a = 10
}
📌 설명:
a는 람다 바깥에 있는 변수입니다.[=]는 a를 값으로 복사해서 람다 안으로 가져옵니다.a를 읽을 수는 있지만, 수정은 못 함.[&] → 참조 캡처 (수정 가능)#include <iostream>
int main() {
int a = 10;
auto lambda = [&]() {
a += 5;
std::cout << "람다 내부: a = " << a << '\n';
};
lambda(); // 출력: 람다 내부: a = 15
std::cout << "람다 외부: a = " << a << '\n'; // 15
}
📌 설명:
[&]는 a를 **참조(주소)**로 캡처합니다.a를 수정하면, 원래 변수도 바뀜.[=] + mutable → 복사인데 수정 가능 (복사본만)#include <iostream>
int main() {
int a = 10;
auto lambda = [=]() mutable {
a += 5;
std::cout << "람다 내부(복사본): a = " << a << '\n';
};
lambda(); // 15
std::cout << "람다 외부: a = " << a << '\n'; // 10 (원본 안 바뀜)
}
📌 설명:
mutable을 붙이면 복사한 변수도 수정 가능해요.a)는 안 바뀜!람다(lambda) 앞에 auto가 붙는 이유는 "람다는 익명 함수이기 때문에 타입을 알 수 없기 때문"입니다.
[](int a, int b) { return a + b; }
이 표현 자체는 "익명 클래스의 객체"입니다. 그런데 이 클래스의 이름이 없기 때문에 아래처럼 직접 쓸 수 없습니다:
익명타입 f = [](int a, int b) { return a + b; }; // ❌ 컴파일 에러
그래서 auto를 써야 합니다:
auto f = [](int a, int b) { return a + b; }; // ✅ OK