본문으로 바로가기

C++14) 일반화 람다 ( Generic lambda )

category C++/Modern 2019. 2. 20. 16:53

<개요>


C++14 에서 새롭게 수정된 일반화 람다 ( Generic lambda ) 와 초기화 캡쳐 ( init capture ) 에 대해 작성합니다.


C++11 람다식 : https://openmynotepad.tistory.com/23


<Generic lambda>


C++14 에서 람다에 대한 타입 추론과 리턴 타입 추론이 새롭게 추가 되었습니다.

인자에 auto 키워드를 사용할 수 있으며 decltype 을 사용할 수 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
std::vector<int> vnt{ 1,2,3,4,5,6,7,8,9,10 };
int result = 0;
 
std::for_each(vnt.begin(), vnt.end(), [&result](auto i) {
    result += i;
});    //i = int
 
auto Add = [](auto i, auto j) ->decltype(i+j) { 
    return i + j;
};
Add(1.56.0);    //7.5
Add(16);    //7
cs

decltype은 생략이 가능합니다.
위 함수는 이와 같습니다.

1
2
3
4
5
6
7
8
struct nonamed {
    template<typename T, typename U>
    auto operator()(T _x, U _y) ->decltype(_x + _y) {
        return _x + _y;
    }
};
 
auto Add = nonamed();
cs

일반화 람다의 경우 auto 에 대한 타입 추론을 해야 하는데, 이 타입 추론 방식은 template 과 유사하다고 합니다. (아예 똑같지는 않다고 합니다.)

<init capture>

람다는 캡쳐 절에서 임시 변수를 생성하고 초기화 할 수 있습니다. 임시 변수의 타입은 자동 추론 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
std::string a = { "wolf" };
cout << a << endl;
[tstr = std::move(a)]{
    cout << tstr ;
}();    // move 로 a 를 가져와 wolf를 출력하고 삭제함 ( tstr은 임시변수라 삭제 됨! )
 
int x = 4;
auto y = [&= x, x = x + 1]()->int
{
    r += 2;    // r == 6
    return x * x;
}(); // 스코프 바깥에있는 x는 6으로 업데이트 되고, y는 25가 됨
cs

Microsoft docs 에서는 std::unique_ptr 같은 객체를 std::move 를 통해 캡쳐하여 이를 람다에 쓸 수 있는 점이 이점이라고 작성돼 있습니다.

1
2
3
4
5
6
pNums = make_unique<vector<int>>(nums);
//무언가 작업을 함
      auto a = [ptr = move(pNums)]()
        {
           // ptr
        };
cs