O código a seguir é compilado com o gcc 4.5.1, mas não com o 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;
}
Este é o erro:
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
Assim,
1> qual compilador está certo?
2> Como posso usar variáveis de membro dentro de um lambda no VS2010?
c++
visual-studio-2010
lambda
c++11
vivek
fonte
fonte
pair<const int, set<int> >
, esse é o tipo de par real de um mapa. Possivelmente também deve ser uma referência a const.Respostas:
Acredito que o VS2010 esteja certo neste momento e verificaria se tinha o padrão à mão, mas atualmente não tenho.
Agora, é exatamente como a mensagem de erro diz: Você não pode capturar coisas fora do escopo do lambda. †
grid
não está no escopo anexo, mas simthis
(todo acesso agrid
realmente acontece comothis->grid
em funções-membro). Para seu caso de usuário, capturarthis
trabalhos, pois você o usará imediatamente e não deseja copiar ogrid
Se, no entanto, você deseja armazenar a grade e copiá-la para acesso posterior, onde seu
puzzle
objeto já pode estar destruído, será necessário fazer uma cópia local intermediária:† Estou simplificando - o Google por "alcançar o escopo" ou consulte §5.1.2 para todos os detalhes sangrentos.
fonte
tmp
ser uma formaconst &
degrid
reduzir a cópia? Ainda queremos pelo menos uma cópia, a cópia no lambda ([tmp]
), mas não precisamos de uma segunda cópia.grid
embora provavelmente seja otimizada. Mais curto e melhor é:auto& tmp = grid;
etc.[grid = grid](){ std::cout << grid[0][0] << "\n"; }
para evitar a cópia extraerror: capture of non-variable ‘puzzle::grid’
Resumo das alternativas:
captura
this
:use uma referência local para o membro:
C ++ 14:
exemplo: https://godbolt.org/g/dEKVGD
fonte
[&grid]
ainda não funciona). Muito feliz em saber isso!Eu acredito que você precisa capturar
this
.fonte
grid
diretamente. Problema sendo, e se você quiser copiar a grade? Isso não permitirá que você faça isso.Um método alternativo que limita o escopo do lambda em vez de fornecer acesso ao todo
this
é passar uma referência local à variável de membro, por exemplo,fonte