프로그래밍/C/C++

C++ lambda expression 람다 표현식

nanze 2022. 1. 4. 11:20
반응형

C++ 11 부터 지원하기 시작한 람다 표현식에 대해서 정리해보자. 

람다 표현식의 구성은 다음과 같다. 

캡쳐블록 + 파라미터 목록 + mutable (생략) + throw (생략) + 리턴타입 (생략) + 함수바디 

[캡쳐블록](파라미터 목록) mutable throw ->리턴타입 {함수바디}

캡쳐블록

캡쳐블록은 [ ] 로 감싸지며 람다 표현식 안에서 참조하는 외부 변수를 지정한다. 변수 지정시 표현식에 따라 의미가 다른데 알아보자.

[=] : 외부 모든 변수 값을 복사하며 객체의 멤버함수에서 람다 호출 시 this 포인터도 전달된다.

       또한 변수 값으로 복사 시에는 const 로 이루어지기 때문에 기본적으로 수정이 되지 않는다. 값으로 복사 된 변수의 값 수정이 필요할 경우

       에는 mutable 키워드를 이용해야 한다. 

[&] : 외부 모든 변수 참조로 복사한다. 

 

위의 표현 방식은 모든 '변수' 라는 접근 방식이고 특정 변수를 지칭할 수도 있다. 

[&i] : i 변수에 대해서만 참조로 캡쳐한다. 

[=i] : i 변수에 대해서만 값으로 캡쳐한다. 

[=, &i] : 기본적으로 모든 변수에 대해서 값으로 캡쳐하고 i 변수에 대해서는 참조로 캡쳐한다. 

[this] : 클래스 멤버 함수의 경우 this 를 전달한다. 

 

C++14 부터는 범위 내 캡쳐 변수가 없어도 캡쳐 블록 내 변수를 선언하고 내부에서 사용할 수 있다. 

auto uniPtr = make_unique<vector<int>>(10);
auto lambdafunc = [p = std::move(uniPtr)]()
    {
        
    }
;

파라미터 목록

람다 표현식에서 내부에서 사용될 파라미터 목록이며 ( ) 으로 감싸진다. 일반적인 함수와 비슷하다.

mutable

캡쳐블록에 복사한 변수는 기본적으로 const 이므로 mutable 키워드를 붙이면 수정이 가능하다.

생략하면 const 속성을 갖는다. 

throw

익셉션 thow 가 필요할 시 작성한다.

리턴타입 

'-> int' 와 같은 방식으로 표현하며 생략할 경우 타입 추론에 의해서 지정된다. 

 

함수바디

실제 수행할 함수 구문이다.

 

다음은 std::function 과 함께 쓰인 코드이다. 

class objFunction
{
    public:
    int operator()()
    {
        return 1;
    }
};

int _function(){
    return 2; 
}

std::function<int()> func = _function;
func = objFunction();
func = [](){ return 3; };
std::function<int(int)> func2 = [](int i){
    return i;
};

위 코드를 보면 std::function 은 템플릿 안에 <리턴타입(파라미터)> 와 같은 형식으로 쓰이며 해당 린턴 타입과 파라미터를 갖는 함수를 받을 수 있다. 위 예제를 보는바와 같이 람다 표현식 대입도 가능하다. 

 

반응형