람다 함수 lambda
// 람다의 포맷
[capture_list](parameters) -> return_type { ... }
// 예시
// int i를 받고 bool 값을 반환하는 함수 객체
[](int i) -> bool { return i % 2 == 1; }
- 리턴 타입을 생략하더라도 컴파일러가 자동으로 추측
// 람다의 포맷
[capture_list](parameters) -> { ... }
// 예시
// int i를 받고 bool 값을 반환하는 함수 객체
auto func = [](int i) { return i % 2 == 1; }
func(4); // false
캡쳐 목록 capture list
- 람다 함수가 스코프 바깥의 로컬 변수에 접근할 수 있도록 도와준다
// 목록에서 2개 이상 지워졌다면 더 이상 지우지 않는 람다 함수 정의
// 그러나 몇개가 지워졌는지는 외부 변수에 정의되어 있다
int num_erased = 0;
// 이때 capture list를 사용한다
vec.erase(std::remove_if(vec.begin(), vec.end(),
[&num_erased](int i) {
if (num_erased >= 2)
return false;
else if (i % 2 == 1) {
num_erased++;
return true;
}
return false;
}),
vec.end());
print(vec.begin(), vec.end());
- 위와 같은 방식으로 람다 함수 내에서 외부에서 정의된 변수를 사용할 수 있다
- &를 붙이지 않으면 num_erased는 원본이 아닌 복사본을 받게 되고, 이때는 const로 받아오기 때문에 값을 변경할 수도 없다
class SomeClass {
std::vector<int> vec;
int num_erased;
public:
SomeClass() {
// ...
// 람다 함수가 멤버 함수에서 사용되고,
// 멤버 변수를 사용해야 한다면 어떨까?
vec.erase(std::remove_if(vec.begin(), vec.end(),
[this](int i) {
if (this->num_erased >= 2)
return false;
else if (i % 2 == 1) {
this->num_erased++;
return true;
}
return false;
}),
vec.end());
}
};
- 위와 같은 상황에서는 this로 SomeClass 자체를 받아와서 사용한다
- 간단히 정리하면
- [] : 아무것도 캡쳐 안함
- [&a, b] : a는 레퍼런스로 캡쳐, b는 (const) 복사본으로 캡쳐
- [&] : 외부의 모든 변수들을 레퍼런스로 캡쳐
- [=] : 외부의 모든 변수들을 복사본으로 캡쳐
출처