아래 링크의 글 중 Herb Sutter 의 Lambda 예제 및 설명에 관한 리플..
http://herbsutter.wordpress.com/2008/03/29/trip-report-februarymarch-2008-iso-c-standards-meeting/

[]와 []안에 들어가는 내용에 대해서 명쾌하게 설명을..




Herb Sutter

Re binders: Okay, I give! I’ll use a better example next time.

(no name) asked: "How are local variables captured?" You have to specify whether it’s by copy or by reference. So this example is illegal because it tries to use a local variable:

    int numWidgets = 0;
    for_each( v.begin(), v.end(), []( Widget& w )
    {
        ++numWidgets;  // error, numWidgets is not in scope
    } );

If you want to update numWidgets directly, capture it by reference:

    for_each( v.begin(), v.end(), [&numWidgets]( Widget& w )
    {
        ++numWidgets;  // increments original numWidgets
    } );
    // numWidgets == v.size() here

Or use the shorthand [&] to take all captured variables implicitly by reference:

    for_each( v.begin(), v.end(), [&]( Widget& w )
    {
        ++numWidgets;  // increments original numWidgets
    } );
    // numWidgets == v.size() here

What if you want a local copy? You say to pass it by value, but for safety reasons the current proposal says you get a read-only copy that you can’t modify:

    for_each( v.begin(), v.end(), [numWidgets]( Widget& w )
    {
        int i = numWidgets; // ok
        ++i;
        // "++numWidgets;" would be an error
    } );
    // numWidgets == 0 here

Or use the shorthand [=] to take all captured variables implicitly by copy:

    for_each( v.begin(), v.end(), [=]( Widget& w )
    {
        int i = numWidgets; // ok
        ++i;
        // "++numWidgets;" would be an error
    } );
    // numWidgets == 0 here

Similarly, for the question: "What will happen in the following case:"

    int flag = 0;
    mypool.run( [] { flag = 1; } );
    cout << flag << endl;

The answer is that the code is illegal, you have to say whether you capture flag by value or by reference, which can be as simple as replacing [] with [=] or [&]. And if you capture by value, you get a read-only copy so you couldn’t assign to it.


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

이미지 변환 모듈 (모바일용, GDI+)  (0) 2010.06.22
C++0x, RValue Reference  (0) 2009.05.27
C++0x 지원 컴파일러 목록  (0) 2009.05.20
C++ Refactoring  (0) 2009.04.14
An Overview of the Coming C++ (C++0x) Standard  (0) 2008.12.29


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>

using namespace std;

#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>

namespace std {
    namespace tr1 = boost;
}


// 테스트용 클래스
class CInt
{
public:
    CInt(int n = 0)
    {
        n_ = n;
    }

    CInt(const CInt &t)
    {
        n_ = t.n_;
    }

    const CInt& operator=(const CInt &t)
    {
        if (this != &t) {
            n_ = t.n_;
        }
        return *this;
    }

    const CInt& operator=(int n)
    {
        n_ = n;
        return *this;
    }

    ~CInt() {}

public:
    void Print(string str) const
    {
        cout << n_ << str;
    }

    int Get() const
    {
        cout << n_;
        return n_;
    }

    operator int() const
    {
        return Get();
    }

   

private:
    int n_;
};


void Write(int n, string str)
{
    cout << n << str;
}
   

int main()
{
    std::vector<int> v;
    std::vector<CInt> vc;

    for (int i = 0; i < 10; ++i) {
        v.push_back(i);
        vc.push_back(i);
    }

    std::random_shuffle(v.begin(), v.end());
    std::random_shuffle(vc.begin(), vc.end());

    string sep = "-";

    // 기존 C++ 바인딩
    for_each(v.begin(), v.end(), bind2nd(ptr_fun(Write), sep));
    cout << endl;

    // 새로운 C++ 바인딩
    for_each(v.begin(), v.end(), tr1::bind(Write, ::_1, sep));
    cout << endl;

    using boost::lambda::_1;

    // lambda 표현식
    for_each(v.begin(), v.end(), cout << _1 << sep  );
    cout << endl;


    // 기존 C++ 바인딩
    for_each(vc.begin(), vc.end(), bind2nd(mem_fun_ref(&CInt::Print), sep));
    cout << endl;

    // 새로운 C++ 바인딩
    for_each(vc.begin(), vc.end(), tr1::bind(tr1::mem_fn(&CInt::Print), ::_1, sep));
    cout << endl;
}

+ Recent posts