El siguiente código se compila con gcc 4.5.1 pero no con 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 es el error:
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
Entonces,
1> qué compilador es el correcto?
2> ¿Cómo puedo usar variables miembro dentro de un lambda en VS2010?
c++
visual-studio-2010
lambda
c++11
vivek
fuente
fuente
pair<const int, set<int> >
, ese es el tipo de par real de un mapa. Posiblemente también debería ser una referencia a const.Respuestas:
Creo que VS2010 tiene razón esta vez, y comprobaría si tenía el estándar a mano, pero actualmente no lo tengo.
Ahora, es exactamente como dice el mensaje de error: no puede capturar cosas fuera del alcance de la lambda. †
grid
no está en el alcance adjunto, pero síthis
(cada acceso agrid
realmente sucede comothis->grid
en las funciones miembro). Para su caso de uso, la capturathis
funciona, ya que la usará de inmediato y no desea copiar elgrid
Sin embargo, si desea almacenar la cuadrícula y copiarla para un acceso posterior, donde su
puzzle
objeto ya podría estar destruido, deberá hacer una copia local intermedia:† Estoy simplificando: Google para "alcanzar el alcance" o ver §5.1.2 para todos los detalles sangrientos.
fuente
tmp
ser unconst &
paragrid
reducir la copia? Todavía queremos al menos una copia, la copia en lambda ([tmp]
), pero no necesitamos una segunda copia.grid
aunque probablemente se optimice. Más corto y mejor es:auto& tmp = grid;
etc.[grid = grid](){ std::cout << grid[0][0] << "\n"; }
para evitar la copia extraerror: capture of non-variable ‘puzzle::grid’
Resumen de las alternativas:
capturar
this
:use una referencia local al miembro:
C ++ 14:
ejemplo: https://godbolt.org/g/dEKVGD
fuente
[&grid]
no funciona). Muy contento de saber esto!Creo que necesitas capturar
this
.fuente
grid
directamente. El problema es, ¿qué pasa si quieres copiar la cuadrícula? Esto no te permitirá hacer eso.Un método alternativo que limita el alcance de la lambda en lugar de darle acceso al conjunto
this
es pasar una referencia local a la variable miembro, por ejemplofuente