ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C++] 람다 함수 활용 방법 (Lambda Expression)
    C++/C++ 실습 2025. 5. 18. 22:17

    람다 함수 (Lambda Expression) 정의

    람다 함수란 이름 없이 정의할 수 있는 익명의 함수를 의미한다. 코드 내에서 간단하게 함수를 정의하고 바로 사용할 수 있다. 그리고 STL (표준 템플릿 라이브러리)와 함께 유용하게 활용될 수 있다.

     

    기본 문법은 다음과 같다.

    [capture_list] (parameters) -> return_type {
        // Function body
    };

     

    • capture_list: 외부 변수를 람다 내에서 사용할 수 있도록 캡쳐하는 부분이다. 람다 함수는 기본적으로 람다 함수가 선언된 영역의 변수를 활용할 수 있다.
    • parameters: 함수의 인자 목록을 의미한다.
    • return_type: 반환 타입이며, 생략 가능하다. 컴파일러가 추론할 수 있다.
    • Function body: 실제 람다의 함수 기능들이 작성되는 구문이다.

     

    외부 변수 캡쳐는 다음과 같이 쓸 수 있다.

    • [ ] : 외부 변수를 캡쳐하지 않는다. 사용하지 않는다는 의미이다
    • [ = ] : 모든 외부 변수를 값으로 캡쳐하며, 읽기전용으로 람다 함수 내부에서 사용할 수 있다.
    • [ & ] : 모든 외부 변수를 참조로 캡쳐하며, 읽기 및 수정이 가능하다.
    • [ x, &y ] : 외부 변수 x를 값으로 캡쳐하고, y는 참조로 캡쳐한다.
    • [ = , &y] : 외부 변수 y는 참조로 캡쳐하고, 나머지 외부 변수는 값으로 캡쳐한다.

     

    람다 함수 (Lambda Expression) 예제

    람다 함수는 다음과 같이 활용될 수 있다.

    #include <iostream>
    
    int main() {
        int x = 10;
        int y = 20;
    
        // 값으로 캡처: [=]
        auto printSum = [=]() {
            std::cout << "Sum: " << (x + y) << std::endl;
        };
    
        printSum(); // Sum: 30
    
        // 참조로 캡처: [&]
        auto increaseX = [&]() {
            x += 5;
        };
    
        increaseX();
        std::cout << "Updated x: " << x << std::endl; // Updated x: 15
    
        return 0;
    }

     

    람다 함수 printSum의 외부 변수, x, y을 값으로 캡쳐하여 x + y 값을 출력하는 코드를 보여준다. 또한 [ & ] 참조로 캡쳐하여 외부 변수를 수정할 수도 있다. 람다 함수는 정의 단계에서 동작하지 않으며, 정의된 이후 실행 부분에서 동작하게 된다.

     

     

    람다 함수 (Lambda Expression) 예제 2

    또한 STL과도 활용될 수 있다. 대표적으로 std::for_each 알고리즘 함수가 있다.

    std::for_each는 반복자 구간 (Iterator Range) 내의 각 원소에 대해 주어진 함수를 실행하는 알고리즘 함수이다. 기본형은 다음과 같다.

    #include <algorithm>  // std::for_each
    #include <iterator>   // std::begin, std::end
    
    std::for_each(first, last, func);
    • first: 반복이 시작될 Iterator
    • last: 반복이 종료될 Iterator
    • func: 각 원소에 대해 실행할 함수 (람다 또는 일반함수)
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    int main() {
        std::vector<int> numbers = {1, 2, 3, 4, 5};
    
        // 모든 원소에 대해 2를 곱한다.
        std::for_each(numbers.begin(), numbers.end(), [](int &n) {
            n *= 2;
        });
    
        // 결과 출력
        for (int n : numbers) {
            std::cout << n << " "; // 2 4 6 8 10
        }
    
        return 0;
    }

     

    std::for_each 함수의 3번째 인자는 함수를 받는데, 람다 함수를 통해, 인자 내부에서 함수 선언을 할 수 있다. 람다 함수 대신, 함수 포인터를 활용할 수도 있다.

     

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    void printSquare(int n) {
        std::cout << n * n << " ";
    }
    
    int main() {
        std::vector<int> numbers = {1, 2, 3, 4, 5};
    
        // 함수 포인터 사용
        std::for_each(numbers.begin(), numbers.end(), printSquare);
    
        return 0;
    }

     

    위 코드에서 std::for-each의 함수인자는 이전에 선언되었던 printSquare가 사용되었다. 

     

    람다 함수 (Lambda Expression) 예제 3

    std::function과도 함께 사용될 수 있다. std::function은 C++11에 도입된 일반화된 함수 래퍼이다. 람다 함수, 함수 포인터, 모두 감쌀 수 있다. 가변적인 함수 타입을 정의할 때 사용된다.

    #include <functional>  // std::function 사용을 위해 필요
    
    std::function<반환타입(인자 목록)> 함수이름;
    • 반환타입: 함수가 반환하는 데이터 타입
    • 인자목록: 함수가 받을 매개변수 타입
    • 함수이름: 함수 객체의 이름

    std::function은 함수를 감싸고 다른 함수에서 인자로 사용될 때 활용될 수 있다.

    #include <iostream>
    #include <functional>
    
    int main() {
        // std::function을 사용해 람다 표현식 감싸기
        std::function<int(int, int)> add = [](int a, int b) {
            return a + b;
        };
    
        int result = add(10, 20); // 람다를 함수처럼 호출
        std::cout << "10 + 20 = " << result << std::endl; // 10 + 20 = 30
    
        return 0;
    }

     

    위 코드에서 람다함수는 std::function 함수인 add에 선언되었고, 이는 다시 여러번 호출되어 활용될 수 있다.

     

    std::function은 다음과 같은 이점을 갖고 있다.

    • 다양한 함수 타입 (람다, 함수 포인터, 일반 함수)등을 하나의 인터페이스로 통합한다.
    • 함수 포인터와 달리, 캡쳐된 람다도 담을 수 있다.
    • 동적으로 함수 변경이 가능하며, Null 상태 체크가 가능하다.
    • 멀티쓰레드 환경에서 안전한 복사가 가능하다.

     

    람다 함수 예시

     

    'C++ > C++ 실습' 카테고리의 다른 글

    [C++] 스마트 포인터 활용하기  (1) 2025.06.01
    [C++] ADL (Argument Dependent Lookup) 이해하기  (0) 2024.11.10
Designed by Tistory.