태그 보관물: lambda

lambda

멤버 함수 내 람다 캡처 목록에서 멤버 변수 사용

다음 코드는 gcc 4.5.1로 컴파일되지만 VS2010 SP1에서는 컴파일되지 않습니다.

#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <set>
#include <algorithm>

using namespace std;
class puzzle
{
        vector<vector<int>> grid;
        map<int,set<int>> groups;
public:
        int member_function();
};

int puzzle::member_function()
{
        int i;
        for_each(groups.cbegin(),groups.cend(),[grid,&i](pair<int,set<int>> group){
                i++;
                cout<<i<<endl;
        });
}
int main()
{
        return 0;
}

이것은 오류입니다 :

error C3480: 'puzzle::grid': a lambda capture variable must be from an enclosing function scope
warning C4573: the usage of 'puzzle::grid' requires the compiler to capture 'this' but the current default capture mode does not allow it

그래서,

1> 어떤 컴파일러가 옳습니까?

2> VS2010의 람다 내에서 멤버 변수를 어떻게 사용할 수 있습니까?



답변

나는 VS2010이 이번에 옳다고 생각하고 표준이 편리한 지 확인하고 있지만 현재는 그렇지 않습니다.

이제는 오류 메시지의 내용과 동일합니다. 람다의 범위를 벗어나는 것은 캡처 할 수 없습니다. grid 는 둘러싸는 범위에 있지 않지만 this( 멤버 함수에서 grid와 같이 실제로 액세스 할 때마다 this->grid) 있습니다. 사용 사례의 경우 캡처 this작업이 즉시 사용되므로 복사 작업을 원하지 않으므로grid

auto lambda = [this](){ std::cout << grid[0][0] << "\n"; }

그러나 그리드를 저장하고 나중에 액세스하기 위해 복사하여 puzzle객체가 이미 파괴 된 경우 중간 로컬 복사본을 만들어야합니다.

vector<vector<int> > tmp(grid);
auto lambda = [tmp](){}; // capture the local copy per copy

† 단순화 중입니다. Google은 “범위에 도달”했거나 모든 세부 사항은 §5.1.2를 참조하십시오.


답변

대안 요약 :

캡처 this:

auto lambda = [this](){};

멤버에 대한 로컬 참조를 사용하십시오.

auto& tmp = grid;
auto lambda = [ tmp](){}; // capture grid by (a single) copy
auto lambda = [&tmp](){}; // capture grid by ref

C ++ 14 :

auto lambda = [ grid = grid](){}; // capture grid by copy
auto lambda = [&grid = grid](){}; // capture grid by ref

예 : https://godbolt.org/g/dEKVGD


답변

나는 당신이 캡처해야한다고 생각합니다 this.


답변

전체에 대한 액세스 권한을 부여하지 않고 람다의 범위를 제한하는 대체 방법 this은 멤버 변수에 대한 로컬 참조를 전달 하는 것 입니다.

auto& localGrid = grid;
int i;
for_each(groups.cbegin(),groups.cend(),[localGrid,&i](pair<int,set<int>> group){
            i++;
            cout<<i<<endl;
   });


답변