다음 코드는 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
답변
나는 당신이 캡처해야한다고 생각합니다 this
.
답변
전체에 대한 액세스 권한을 부여하지 않고 람다의 범위를 제한하는 대체 방법 this
은 멤버 변수에 대한 로컬 참조를 전달 하는 것 입니다.
auto& localGrid = grid;
int i;
for_each(groups.cbegin(),groups.cend(),[localGrid,&i](pair<int,set<int>> group){
i++;
cout<<i<<endl;
});