[C++] 람다 표현식
📌 C++ 람다 표현식(Lambda Expression)
C++에서 람다 표현식(lambda expression)**은 익명 함수(Anonymous Function)를 생성하는 기능이다.
즉, 함수의 이름 없이 즉석에서 정의하고 사용할 수 있는 간단한 함수이다.
📢 기존의 함수 포인터나 std::function보다 간결하게 함수를 정의하고 사용할 수 있음!
✅ 람다 표현식 기본 문법
[캡처](매개변수) -> 반환형 { 함수 본문 };
요소 | 설명 |
[] | 캡처(Capture): 람다 내부에서 외부 변수 접근 여부 지정 |
() | 매개변수(Parameter): 일반 함수처럼 매개변수 지정 |
-> 반환형 | (선택 사항) 반환형 명시 (auto로 생략 가능) |
{} | 함수 본문(Body): 람다에서 실행할 코드 |
✅ 기본적인 람다 표현식 예제
🔹 가장 단순한 형태의 람다
#include <iostream>
int main() {
auto hello = []() { std::cout << "Hello, Lambda!" << std::endl; };
hello(); // 결과: Hello, Lambda!
return 0;
}
✔ hello 변수에 람다 표현식을 저장하고, hello();를 호출하여 실행.
🔹 매개변수와 반환값을 가지는 람다
#include <iostream>
int main() {
auto add = [](int a, int b) -> int { return a + b; };
std::cout << add(3, 4) << std::endl; // 결과: 7
return 0;
}
✔ [] 내부에는 캡처 리스트가 없고, (int a, int b)는 매개변수
✔ -> int는 반환형 지정 (생략 가능)
✔ { return a + b; }는 함수 본문
✅ 캡처 리스트(Capture)
람다 표현식 내부에서 외부 변수에 접근하려면 캡처 리스트를 사용해야 한다.
1️⃣ 값으로 캡처(=)
#include <iostream>
int main() {
int x = 10;
auto lambda = [=]() { std::cout << "x: " << x << std::endl; };
lambda(); // 결과: x: 10
return 0;
}
✔ [=]은 외부 변수 x를 값으로 복사하여 사용 (읽기 전용)
✔ 람다 내부에서 x의 값을 변경할 수 없음.
2️⃣ 참조로 캡처(&)
#include <iostream>
int main() {
int x = 10;
auto lambda = [&]() { x += 5; };
lambda();
std::cout << "x: " << x << std::endl; // 결과: x: 15
return 0;
}
✔ [&]은 외부 변수를 참조로 캡처하여 람다 내부에서 수정 가능.
✔ x가 원본 변수의 값을 직접 변경함.
3️⃣ 특정 변수만 캡처
#include <iostream>
int main() {
int a = 5, b = 10;
auto lambda1 = [a]() { std::cout << "a: " << a << std::endl; };
auto lambda2 = [&b]() { b *= 2; };
lambda1(); // 결과: a: 5
lambda2();
std::cout << "b: " << b << std::endl; // 결과: b: 20
return 0;
}
✔ [a] → 변수 a만 값 복사
✔ [&b] → 변수 b만 참조 캡처
4️⃣ 혼합 캡처
#include <iostream>
int main() {
int a = 3, b = 5;
auto lambda = [=, &b]() { b += a; };
lambda();
std::cout << "b: " << b << std::endl; // 결과: b: 8
return 0;
}
✔ [=, &b] → 기본적으로 값 캡처(=), 하지만 b는 참조 캡처(&b)
✔ b만 원본 값 변경 가능, a는 읽기 전용
✅ 람다와 std::function
람다는 std::function과 함께 사용 가능하다.
#include <iostream>
#include <functional>
int main() {
std::function<int(int, int)> func = [](int a, int b) { return a + b; };
std::cout << func(3, 4) << std::endl; // 결과: 7
return 0;
}
✔ std::function을 사용하면 람다를 일반적인 함수 포인터처럼 다룰 수 있음.
✅ 람다 표현식과 mutable
기본적으로 람다는 값 캡처(=)를 사용하면 캡처한 변수를 변경할 수 없음.
하지만 mutable 키워드를 사용하면 변경 가능하다.
#include <iostream>
int main() {
int x = 10;
auto lambda = [x]() mutable { x += 5; std::cout << "x: " << x << std::endl; };
lambda(); // 결과: x: 15
std::cout << "Original x: " << x << std::endl; // 결과: Original x: 10
return 0;
}
✔ mutable을 사용하면 람다 내부에서 x의 값을 변경 가능
✔ 하지만 원본 변수(x)는 그대로 유지됨!
✅ 람다를 반환하는 함수
람다를 반환하려면 반환형을 auto 또는 std::function으로 설정해야 한다.
1️⃣ auto 반환
#include <iostream>
auto getLambda() {
return [](int x) { return x * 2; };
}
int main() {
auto func = getLambda();
std::cout << func(10) << std::endl; // 결과: 20
return 0;
}
2️⃣ std::function 사용
#include <iostream>
#include <functional>
std::function<int(int)> getLambda() {
return [](int x) { return x * 2; };
}
int main() {
std::function<int(int)> func = getLambda();
std::cout << func(10) << std::endl; // 결과: 20
return 0;
}
✔ std::function을 사용하면 반환되는 람다의 타입을 명확하게 지정 가능
🔥 결론
✅ 람다 표현식은 이름 없는 함수(익명 함수)를 정의하는 문법
✅ 캡처 리스트([])를 사용하여 외부 변수 접근 가능
✅ 값 캡처(=), 참조 캡처(&), 특정 변수 캡처 가능
✅ mutable 키워드를 사용하면 값 캡처 변수도 변경 가능
✅ std::function을 사용하면 람다를 더 유연하게 활용 가능
🚀 람다 표현식을 활용하면 코드가 더 간결해지고 가독성이 좋아진다!