Der folgende Code wird mit gcc 4.5.1 kompiliert, jedoch nicht mit 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;
}
Dies ist der Fehler:
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
So,
1> Welcher Compiler ist richtig?
2> Wie kann ich Mitgliedsvariablen in einem Lambda in VS2010 verwenden?
c++
visual-studio-2010
lambda
c++11
vivek
quelle
quelle
pair<const int, set<int> >
, dass dies der tatsächliche Paartyp einer Karte ist. Es sollte möglicherweise auch ein Verweis auf const sein.Antworten:
Ich glaube, dass VS2010 diesmal richtig ist, und ich würde prüfen, ob ich den Standard zur Hand habe, aber derzeit nicht.
Jetzt ist es genau so, wie in der Fehlermeldung steht: Sie können keine Inhalte außerhalb des umschließenden Bereichs des Lambda erfassen. †
grid
befindet sich nicht im umschließenden Bereich, ist es aberthis
(jeder Zugriff auf erfolgtgrid
tatsächlich wiethis->grid
in Mitgliedsfunktionen). Für Ihren Anwendungsfallthis
funktioniert das Erfassen , da Sie es sofort verwenden und das nicht kopieren möchtengrid
Wenn Sie das Raster jedoch speichern und für den späteren Zugriff kopieren möchten, wo Ihr
puzzle
Objekt möglicherweise bereits zerstört ist, müssen Sie eine lokale Zwischenkopie erstellen:† Ich vereinfache - Google für "Erreichen des Geltungsbereichs" oder siehe §5.1.2 für alle wichtigen Details.
quelle
tmp
sein , einconst &
zugrid
auf Kopieren zu reduzieren? Wir wollen immer noch mindestens eine Kopie, die Kopie in das Lambda ([tmp]
), aber keine Notwendigkeit für eine zweite Kopie.grid
obwohl sie wahrscheinlich optimiert wird. Kürzer und besser ist:auto& tmp = grid;
usw.[grid = grid](){ std::cout << grid[0][0] << "\n"; }
die zusätzliche Kopie vermeidenerror: capture of non-variable ‘puzzle::grid’
Zusammenfassung der Alternativen:
erfassen
this
:Verwenden Sie einen lokalen Verweis auf das Mitglied:
C ++ 14:
Beispiel: https://godbolt.org/g/dEKVGD
quelle
[&grid]
funktioniert es immer noch nicht). Sehr froh das zu wissen!Ich glaube, du musst erfassen
this
.quelle
grid
. Problem ist, was ist, wenn Sie das Raster kopieren möchten? Dies wird Ihnen nicht erlauben, dies zu tun.Eine alternative Methode, die den Umfang des Lambda einschränkt, anstatt ihm Zugriff auf das Ganze
this
zu gewähren, besteht darin, einen lokalen Verweis auf die Mitgliedsvariable zu übergeben, zquelle