익명 함수 객체를 생성하여 콟백, 일회성 함수로 코드를 간결하고 가독성 좋게 유지하는 데 도움
기본 문법 구조
[capture](params) mutable exception attribute -> return_type {
// 함수 본문
}- capture: 람다 외부 변수를 함수 내부에서 쓸 수 있게 지정
[]: 외부 변수 사용 x[&]: 모든 외부 변수를 참조로 캡쳐[=]: 모든 외부 변수를 값으로 캡쳐[x, &y]: x는 값으로, y는 참조로 캡쳐[this]: 멤버 함수 내에서 사용시 현재 객체의 포인터를 캡처[*this]: 객체의 복사본 값을 캡처
- params: 매개변수 정의
- mutable: 값으로 캡쳐한 변수를 람다 본문 내에서 수정
- exception:
noexcept처럼 람다 함수가 예외를 발생시키는지 여부를 명시 - attribute: nodiscard 처럼 람다 함수에 속성 부여
- return_type: 생략 시 컴파일러가 자동 추론
- {}: 함수 본문
Examples
#include <iostream>
#include <vector>
struct Person {
std::string name;
int age;
};
int main() {
// 기본적인 사용법
auto add = [](int a, int b) { return a + b; };
std::cout << "add(5,3) = " << add(5, 3) << std::endl;
// 반환타입 명시적 지정
auto multiply = [](double a, double b) -> double { return a * b; };
std::cout << "multiply(2.5, 4.0) = " << multiply(2.5, 4.0) << std::endl;
// capture절 사용
int x = 10;
int y = 20;
// 값으로 capture
auto lambda_val_capture = [=]() -> void {
std::cout << "Captured value x:" << x << " y:" << y << std::endl;
};
lambda_val_capture();
// 참조로 capture
auto lambda_ref_capture = [&]() -> void {
x = 100;
y = 200;
};
lambda_ref_capture();
// 람다 외부에서 선언된 x,y 변수 변경됨
std::cout << "Captured ref x:" << x << " y:" << y << std::endl;
// mutable 키워드 사용하여 값으로 capture된 변수 수정
int count = 0;
auto increment_captured_count = [count]() mutable {
count++;
std::cout << "Mutable lambda count:" << count << std::endl;
};
increment_captured_count();
increment_captured_count();
// 원본 count는 증가하지 않음
std::cout << "Original value count:" << count << std::endl;
// STL 알고리즘과 함께 사용
std::vector<int> numbers = {6, 4, 2, 7, 5, 9, 8};
// 내림차순 정렬
std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });
// for_each와 람다 사용한 출력
std::cout << "Sorted vector : ";
std::for_each(numbers.begin(), numbers.end(),
[](int n) { std::cout << n << " "; });
std::cout << std::endl;
// find_if와 람다로 첫 번째 짝수 찾기
int first_even_threshold = 3;
auto it_even = std::find_if(
numbers.begin(), numbers.end(), [first_even_threshold](int num) {
return (num % 2 == 0) && (num > first_even_threshold);
});
(it_even != numbers.end())
? std::cout << "First even number greater than threshold : " << *it_even
<< std::endl
: std::cout << "No even number found";
// generic 람다 (c++14부터)
auto generic_add = [](auto a, auto b) { return a + b; };
std::cout << "generic_add(5, 3) : " << generic_add(5, 3) << std::endl;
std::cout << "generic_add(2.5, 3.0) : " << generic_add(2.5, 3.0) << std::endl;
// std::function으로 람다 저장
std::function<int(int, int)> func_add = [](int a, int b) { return a + b; };
std::cout << "func_add(5,3) : " << func_add(5, 3) << std::endl;
//=============================================//
// 일반화된 캡처 (추가 공부 필요)
auto ptr = std::make_unique<int>(42);
// ptr의 소유권을 람다로 옮김
auto generalized_capture_lambda = [value = std::move(ptr)]() {
if (value) {
std::cout << "6. Generalized capture: Value is " << *value << std::endl;
} else {
std::cout << "6. Generalized capture: Value is nullptr" << std::endl;
}
};
generalized_capture_lambda();
// 이제 main 함수의 ptr은 nullptr (또는 유효하지 않은 상태)
if (!ptr) {
std::cout << " Original ptr is now null after std::move." << std::endl;
}
return 0;
}