Visual Studio 2010 공식 팀 블로그 @vsts2010

Posted by 흥배

클로져 사용하기 2

 

<Code 4> 에서는(세 번째 글의 마지막 예제) 하나의 변수만을 캡쳐했지만 복수의 변수를 캡쳐하는 것도 가능할까요? 네 당연히 가능합니다.


‘[]’ 사이에 캡쳐할 변수를 선언하면 됩니다.

[ &Numb1, &Numb2 ]

 

그럼 ‘[&]’로 하면 어떻게 될까요? 이렇게 하면 람다 식을 정의한 범위 내에 있는 모든 변수를 캡쳐할 수 있습니다.

 

< Code 6. >

int main()

{

           vector< int > Moneys;

           Moneys.push_back( 100 );

           Moneys.push_back( 4000 );

           Moneys.push_back( 1001 );

           Moneys.push_back( 7 );

 

           int TotalMoney1 = 0;

           int TotalBigMoney = 0;

 

        // Money 1000 보다 크면 TotalBigMoney에 누적합니다.

           for_each(Moneys.begin(), Moneys.end(), [&](int Money) {

             TotalMoney1 += Money;

             if( Money > 1000 ) TotalBigMoney += Money;

           });

          

           cout << "Total Money 1 : " << TotalMoney1 << endl;

           cout << "Total Big Money : " << TotalBigMoney << endl;

 

           return 0;

}

 

< 결과 >






람다 식을 STL 컨테이너에 저장

 

람식 식을 STLfunction을 사용하여 STL 컨테이너에 저장을 할 수 있습니다.

아래는 int를 반환하는 람다 식을 vector에 저장하여 사용하는 것입니다.

 

< Code 6. >

#include <iostream>

#include <algorithm>

#include <functional>

#include <vector>

 

using namespace std;

 

 

int main()

{

    vector<function<int()>> v;

 

v.push_back( [] { return 100; } );

    v.push_back( [] { return 200; } );

 

cout << v[0]() << endl;

cout << v[1]() << endl;

}

 

< 결과 >






람다 식에서 클래스의 멤버 함수 호출

 

클래스의 멤버 함수 내에 람다 식을 정의하고, 이 람다 식에서 해당 클래스의 멤버를 호출 할 수 있습니다. 클래스 멤버 내의 람다 식은 해당 클래스에서는 friend로 인식하므로 람다 식에서 private 멤버의 접근도 할 수 있습ㄴ다.

그리고 클래스의 멤버를 호출할 때는 ‘this’를 캡쳐합니다.

 

< Code 7. >

class NetWork

{   

public:

    NetWork()

    {

        SendPackets.push_back(10);

        SendPackets.push_back(32);

        SendPackets.push_back(24);

    }

 

    void AllSend() const

    {

        for_each(SendPackets.begin(), SendPackets.end(), [this](int i){ Send(i); });

    }

 

private:

           vector< int > SendPackets;

 

          void Send(int PacketIndex) const

          {

                     cout << "Send Packet Index : " << PacketIndex << endl;

          }

};

 

int main()

{

    NetWork().AllSend();

 

           return 0;

}

 

< 결과 >



<Code 7> Network 클래스의 멤버 함수 AllSend()에서 람다 식을 사용했습니다.

 for_each(SendPackets.begin(), SendPackets.end(), [this](int i){ Send(i); });

보시다시피 ‘[]’ 사이에 ‘this’를 기술하였고, Network 클래스의 private 멤버 함수인 Send를 호출하고 있습니다. 당연히 멤버 변수도 호출 할 수 있습니다.

 

 

 

람다 식에서의 재귀

 

람다는 재귀도 가능합니다.


< Code 8. >

int main()

{

    function<int(int)> fact = [&fact](int x) {

        return x == 0 ? 1 : x * fact(x - 1);

    };

 

    cout << fact(3) << endl;

}

 

fact변수를 참조로 넘겨서 재귀를 하고 있습니다.

 

출처 : http://d.hatena.ne.jp/faith_and_brave/20081119/1227087326

 

 

 

auto와 람다

 

람다 식을 auto에 대입하여 사용할 수 있습니다.

< Code 7>에서 람다를 사용했던

for_each(SendPackets.begin(), SendPackets.end(), [this](int i){ Send(i); });

auto 사용하여 바꾸면 아래와 같이 됩니다.

 

auto myLambdaFunc = [this]( int i ) { this->Send(i); };

for_each(SendPackets.begin(), SendPackets.end(), myLambdaFunc );

 

람다를 폭 넓게 사용할 때 auto를 같이 사용하면 간결한 코드를 만들 수 있을 것 같습니다.

 

 


이것으로 람다에 관한 이야기를 마무리하려고 합니다.

부족함이 많은 글이지만 C++0x의 람다에 관한 내용은 대부분 다 소개했다고 생각합니다.

다만 아직 람다는 더 깊이 팔 수 있는 것입니다.^^;

그래서 다음에 또 기회가 된다면 이번보다 좀 더 깊은 내용 소개하도록 하겠습니다.

 

원래는 람다를 끝으로 'Concurrency Runtime'에 대한 것을 설명하려고 했는데 VC++ 10에 추가된 C++0x 기능 중 'decltype'이라는 것이 있어서 이것까지 하고 난 후 들어가려고 합니다.

그러니 다음 주에 올릴 'decltype'도 기대해 주세요^^


저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

'C++0x' 카테고리의 다른 글

대용량 파일 조작을 위한 C++0x의 변화  (0) 2009/09/07
[VC++] 14. decltype  (0) 2009/06/30
[VC++] 13. Lambda - 네 번째  (3) 2009/06/23
[VC++] 12. Lambda - 세 번째  (0) 2009/06/16
[VC++] 11. Lambda - 두 번째  (0) 2009/06/09
[VC++] 9. Lambda ( 람다 ) - 첫 번째  (4) 2009/06/02

댓글을 달아 주세요

  1. 라도파 2009/08/24 07:27

    아주 재미있었습니다...^^

  2. 왕종선 2010/08/10 12:46

    VS2005를 쓰느라 함수객체로 도배를 자주 했는데..
    람다를 보니까 너무 부럽네요.;
    흠 C++ 0x로 빨리 갈아타야 하는데..;

    (boost 에도 lambda 는 있긴 있습니다만 뭔가.. 부족한... ㅠㅠ)

  3. 잘 배웠습니다. 감사합니다.