On this page
article
Change in Lambda
람다 표현식의 변화
1. auto 매개변수 (C++14~)
- C++14부터 람다 표현식에서
auto
를 파라미터 타입으로 사용 가능 - 컴파일러가 두 개의 템플릿 인자를 가진 함수를 만들어주기 때문
auto add = [](auto a, auto b) { return a + b; };
- 서로 다른 타입 허용, 제약하려면 template 사용
auto add2 = []<typename T>(T a, T b) { return a + b; };
// add2<int>(1, 2.2); // 오류, T는 동일 타입이어야 함
2. 평가되지 않은 표현식에서의 람다 (C++20~)
C++20부터 람다 표현식을 다음 네 가지 문맥에서 사용할 수 있음 (평가되지 않은 표현식)
sizeof
decltype
typeid
noexcept
예시 (기존에는 불가)
std::unique_ptr<int, decltype([](int* p) { delete p; })> up(new int);
3. 캡처 없는 람다: 복사/대입 지원 (C++20~)
int main()
{
int v1 = 10;
auto f1 = [v1](int a, int b) {return a + b;};
// C++11 ~ C++17 C++20
decltype(f1) f2; // Error Error
decltype(f1) f3 = f1; // OK OK
f3 = f1; // Error Error
/*
auto f1 = [](int a, int b) {return a + b;};
// C++11 ~ C++17 C++ 20
decltype(f1) f2; // Error OK
decltype(f1) f3 = f1; // OK OK
f3 = f1; // Error OK
*/
}
- C++20부터 캡처가 없는 경우에는 디폴트 생성자와 대입 연산자 지원
4. 암묵적 this 캡처 제거 (C++20에서 deprecated)
- 기존:
[=]
캡처는this
를 암묵적으로 포함했음 - 문제:
this
가 파괴된 뒤 접근하면 정의되지 않은 동작 발생
안전한 대안
// [=] 에서 this를 명시적으로 분리
[=, this] // 명시적 캡처 (복사)
[=, *this] // 멤버 값 복사
예시 코드
struct Sample {
int value = 0;
auto foo() {
int n = 10;
auto f = [=, *this](int a) { return a + n + value; };
return f;
}
};
std::function<int(int)> f;
void goo() {
Sample s;
f = s.foo();
std::cout << f(10) << std::endl;
}
int main() {
goo();
std::cout << f(10) << std::endl;
}
5. Capture Parameter Pack (C++20~)
- 가변 인자를 캡처 가능
값으로 캡처
template<typename ... Args>
auto f1(Args&&... args) {
return [...args = std::forward<Args>(args)]() {
(std::cout << ... << args);
};
}
참조로 캡처
template<typename ... Args>
auto f2(Args&&... args) {
return [&...args = std::forward<Args>(args)]() {
(std::cout << ... << args);
};
}
요약
기능 | 도입 버전 | 설명 |
---|---|---|
auto 매개변수 람다 | C++14 | 타입 추론 가능한 일반화 람다 |
평가되지 않은 표현식에서 람다 | C++20 | decltype, sizeof 등에 람다 사용 가능 |
캡처 없는 람다 복사/대입 지원 | C++20 | 디폴트 생성자 및 대입 연산자 사용 가능 |
this 의 암묵적 캡처 제거 (deprecated) | C++20 | 명시적으로 [=, this] 또는 [=, *this] 필요 |
가변 인자 캡처 | C++20 | 파라미터 팩을 값 또는 참조로 캡처 가능 |