람다 표현식
함수의 익명 표기법이다.
일급 함수 및 순수 함수를 만들 때 용이하다.
람다식은 크게 캡처 목록 [], 매개변수 목록 (), 본문 {} 3가지로 구성되어있다.
간단한 함수를 람다로 표현하기
한 번만 실행되는 한 줄짜리 간단한 함수의 경우 클래스의 멤버 함수나 전역 함수로 만들기보다는 사용되는 곳에 직접 정의하면 가독성 향상 및 최적화될 가능성이 높아진다.
std::for_each(std::begin(vehicles), std::end(vehicles), PrintOut); /* 기존 방법 */
std::for_each(std::begin(vehicles),
std::end(vehicles),
[](const Vehicle &vehicle) {
std::cout << vehicle.GetType << '\n';
});
여러 줄의 함수를 람다로 표현하기
한줄 뿐만 아니라 여러줄의 함수도 람다 표현식으로 만들 수 있다.
std::for_each(std::begin(vect),
std::end(vect),
[](int n) {
std::cout << n << " is";
if (n < 2) {
if (n == 0) std::cout << " not";
}
else {
for (int j = 2; j < n; ++j) {
if (n % j == 0) {
std::cout << " not";
break;
}
}
}
std::cout << " prime number" << '\n';
});
람다 표현식에서 값 반환
std::transform(std::begin(vect2),
std::end(vect2),
begin(vect3),
[](int n) -> double {
return n / 2.0;
});
람다 표현식에서 값 반환시 타입 명시가 필요하다면 매개 변수와 본문 사이에 명시해주면 된다.
명시하지 않으면 컴파일러가 추정한다.
람다 표현식에서 값 캡처하기
[=](int){ ... }; // 외부 변수 값 복사
[&](int){ ... }; // 외부 변수 참조
[=, &a](int){ ... }; // 외부 변수 값 복사. 단, a만 참조
외부 변수를 값 복사로 캡처하면 const화 되기때문에 수정이 불가능하다.
하지만 값을 수정하되 외부에 영향을 미치지 않고 싶다면(call by value) mutable 키워드를 추가하면 된다.
int a = 1;
int b = 2;
std::for_each(std::begin(vect),
std::end(vect),
[=](int& x) mutable {
int old = a;
a = b;
b = old;
});
덧붙여서 [=], [&] 같은 암시적 캡처의 사용은 절대적으로 지양하는것이 좋다. 필요한 것만 명시적으로 캡처해야한다.
초기화 캡처
C++14부터 추가된 기능이다.
외부 변수의 값을 캡처해서 람다 표현식의 변수에 할당할 수 있다.
int a = 5;
auto myLambda = [&x = a]() { x += 2; }; /* 람다에서 사용하는 x에 a값을 대입한다 */
myLambda();
std::cout << a << '\n'; /* 람다식에 의해 2가 증가했으므로 7이 출력된다 */
외부 변수 참조 캡처와 같아보이지만 복사가 불가능한 unique_ptr같은 이동 전용 변수도 캡처하여 람다에서 사용할 수 있다.
pNums = std::make_unique<std::vector<int>>(nums);
auto a = [ptr = std::move(pNums)]() { ... }; /* 단순히 pNums를 값으로 캡처하면 오류가 발생한다 */
위와 같은 경우는 캡처될 때 move가 사용되었으므로 pNums는 empty가 된다.
제너릭 람다 표현식
C++14부터 람다 표현식의 매개변수에 auto 타입이 사용가능해졌다.
auto findMax = [](auto &x, auto &y) { return x > y ? x : y; };
추가로 C++17부터는 캡처 목록에 *this를 사용해서 객체의 복사본을 캡처할 수 있다.
또한 람다 표현식으로 constexpr 객체를 컴파일 타임에 생성할 수 있다.
constexpr
객체나 함수 앞에 붙일 수 있는 키워드. 해당 객체나 함수의 반환값을 컴파일 타임에 알 수 있다는 의미를 명시한다.
'도서 > 모던 C++로 배우는 함수형 프로그래밍' 카테고리의 다른 글
함수형 프로그래밍에서 함수 다루기 (2) (0) | 2022.12.09 |
---|---|
함수형 프로그래밍에서 함수 다루기 (1) (0) | 2022.12.09 |
모던 C++와 친숙해지기 (4) (0) | 2022.12.09 |
모던 C++와 친숙해지기 (2) (0) | 2022.12.08 |
모던 C++와 친숙해지기 (1) (0) | 2022.12.08 |