36. 람다 클로저 타입의 내부 동작과 캡처 저장

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// 주제: 람다(lambda)의 클로저 타입(closure type) 내부 동작
//
// 컴파일러는 각 람다 식마다 이름 없는 고유 클래스(클로저 타입)를 생성한다. 캡처는 그
// 클래스의 멤버로 저장되고, 람다 본문은 operator() 가 된다. 캡처 방식(값/참조)·mutable·
// 캡처 시점이 sizeof 와 관측 값에 어떻게 반영되는지를 예측·설명하는 문제다.
//
// 과제:
//  1) 아래 프로그램의 출력을 한 줄씩 예측하라.
//  2) 각 sizeof 값이 왜 그렇게 나오는지(빈 클로저·값 캡처·참조 캡처의 저장 형태)를 설명하라.
//  3) l2 와 l4 가 outer 변경(a=100) 뒤 다른 값을 내는 이유, mutable 람다 l5 의 상태가
//     어디에 저장되고 outer 에 영향을 주지 않는 이유를 설명하라.

#include <iostream>

int main() {
    int a = 10, b = 20;

    auto l1 = []          { return 1; };          // 캡처 없음
    auto l2 = [a]         { return a; };          // a 값 캡처
    auto l3 = [a, b]      { return a + b; };       // 두 값 캡처
    auto l4 = [&a]        { return a; };          // a 참조 캡처
    auto l5 = [a]() mutable { return ++a; };      // 값 캡처 + mutable

    std::cout << sizeof(l1) << "\n";
    std::cout << sizeof(l2) << "\n";
    std::cout << sizeof(l3) << "\n";
    std::cout << sizeof(l4) << "\n";

    a = 100;                                       // outer a 변경

    std::cout << l2() << "\n";
    std::cout << l4() << "\n";
    std::cout << l5() << "\n";
    std::cout << l5() << "\n";
    std::cout << a << "\n";
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.