반응형

일반 함수는 [반환형], [함수 이름], [인수] 를 입력하여 선언한다. 

하지만 람다 함수는 이름이 없는 익명 함수로써 아래의 형태로 선언하여 사용하며, std::function 과 함께 사용시 재사용도 가능하다. 

(참고 : std::function - 함수 포인터를 대체하는 키워드)

 

1. 사용법

- 람다 함수는 캡처(Capture), 인자(Parameter), 반환형(Return-Type), 바디(Body) 로 구성되어 있다.
- 캡처와 인자는 콤마(,)로 구분하여 여러 개 지정할 수 있다.

[capture] (parameter) -> return-type { body };

 

(1) 캡처(Capture)

- 캡처는 람다 함수에서 사용할 변수나 상수를 참조나 복사의 형태로 찍어오는 것이다.
- 전역 변수를 참조로 캡처할때는 [&], 복사로 캡처할때는 [=]를 사용한다.
- 지역 변수를 참조로 캡처할때는 [&변수명], 복사로 캡처할때는 [=변수명]을 사용한다.

[&]() { return; } // 모든 변수를 참조로 캡처
[=]() { return; } // 모든 변수를 복사로 캡처
[&var1, var2]() { return; } // var1은 참조, var2는 복사로 캡처
[=, &var1]() { return; } // var1만 참조로 캡처하고, 다른 변수는 복사로 캡처
[&, var2]() { return; } // var2만 복사로 캡처하고, 다른 변수는 참조로 캡처

 

- 복사로 캡처된 변수는 기본적으로 constexpr 타입으로 지정되어 값의 변경이 불가하다.

- mutable로 선언하면 값의 변경이 가능하다.

int var1{0};

[var1]() {
    var1 = 999; // 에러!!! - var1은 constexpr 타입이므로 변경이 불가
}();
[var1]() mutable {
    var1 = 999; // var1은 mutable로 선언되어 변경이 가능, 단 실제 값은 변하지 않음
    std::cout << var1 << std::endl; // 999
}();

std::cout << var1 << std::endl; // 0

 

(2) 인자(Parameter)

- 일반 함수의 인자처럼 람다 함수에서 사용할 인자를 지정한다.

[](int a) -> int { return a; } // 1개의 인자를 설정
[](int a, int b) -> int { return (a+b); } // 2개의 인자를 설정


(3) 반환형(Return-Type)

- 람다 함수의 실행 결과를 반환할 반환 타입을 지정한다.


(4) 바디(Body)

- 람다 함수에서 수행할 작업을 기술한다.

 

2. 사용 예제

#include <iostream>
#include <functional>

int main()
{
    // 간단한 람다 함수
    []() {
        std::cout << "Simple Lamda Function" << std::endl;
    }();
    
    // 인자 2개를 더해서 sum에 저장하고, 더한 값을 반환하는 람다 함수
    int sum{0};
    // std::function 에 람다 함수를 정의
    std::function<int(int,int)> fSum{[&sum](int a, int b) -> int {
        sum = a + b;
        return sum;
    }};

    std::cout << fSum(10, 20) << std::endl; // 30
    std::cout << sum << std::endl; // 30
    
    return 0;
}

 

3. 사용 예제 (클래스에서 사용)

#include <iostream>
#include <functional>
#include <string>

class Person
{
public:
    Person(std::string&& pName, int pAge, std::function<std::string(std::string&, int)>&& pFunc)
        : mName(std::move(pName))
        , mAge(pAge)
        , mTagFunc(std::move(pFunc)) // 람다 함수로 전달받은 임시 함수(r-value)를 std::move를 사용해 저장
    {
        // 출력 람다 함수에서 클래스의 멤버 변수를 사용하기 위해 this를 캡처한다.
        mPrintFunc = [this]() {
            std::cout << "Name: " << mName << ", Age: " << mAge
                << ", Tag: " << mTag << std::endl;
        };
    }

    void executeTagFunc()
    {
    	// 태그 생성 람다 함수 호출
        mTag = mTagFunc(mName, mAge);
    }

    void executePrintFunc()
    {
    	// Person 정보 출력 람다 함수 호출
        mPrintFunc();
    }

private:
    std::function<std::string(std::string&, int)> mTagFunc{};
    std::function<void()> mPrintFunc{};

    std::string mName{};
    std::string mTag{};
    int mAge{0};
};

int main()
{
    // 객체 생성시 [이름], [나이], [태그 생성 함수]를 인자로 받음
    Person ps("Simson", 44, [](std::string& pName, int pAge) -> std::string {
        return std::string(pName + "-" + std::to_string(pAge));
    });

    ps.executeTagFunc();
    ps.executePrintFunc();

    return 0;
}


 

반응형

+ Recent posts