2014-06-29 11 views
9

Właśnie zacząłem uczyć się funkcji lambda w C++ i nie rozumiem dlaczego lambda pozwala na przechwytywanie tylko zmiennych automatycznych pamięci masowej? Na przykład:Dlaczego lambda przechwytuje tylko zmienne automatyczne?

int x; 
int main() { 
    [&x](int n){x = n;}; // 'x' cannot be captured... 
    return 0; 
} 

Z drugiej strony zmienne statyczne nie trzeba wcale przechwytywania

static int s = 0; 
[](int n){s = n;}; 

tak, to dlaczego pierwszy przykład nie jest dozwolone, a drugi działa?

+3

Nie chodzi o statycznym eliminacjach tyle, ile chodzi o zakres zmiennej http://ideone.com/2qVDaX Ponieważ globalny będą widoczne w lambda niezależnie, przechwytywanie jest zbędne. – StoryTeller

+0

możliwy duplikat [Can a C++ 11 lambda przechwytuje zmienną zakresu pliku?] (Http://stackoverflow.com/questions/20361865/can-a-c11-lambda-capture-a-file-scope-variable) – Pradhan

+3

Myślę, że to interesujące, że porównujesz te dwa przykłady, jakby zachowywały się inaczej. Jeśli sprawisz, że pierwsza nie spróbuje uchwycić 'x' (jak w drugim), to działa. –

Odpowiedz

10

Musisz zmienić zakres. Spójrz na to:

int x = 4; 

int main() 
{ 
    cout << "::x = " << ::x << endl; 

    [&](int a){ ::x = a; }(2); 

    cout << "::x = " << ::x << endl; 

    return 0; 
} 

wyjściowa:

::x = 4 
::x = 2 
+0

tak. Widziałem to. Ale dlaczego muszę określać nazwy zmiennych automatycznego składowania w przechwytywaniu [], a nie globalne? Dlaczego po prostu nie używać zmiennych automatycznych do przechowywania jako zmiennych globalnych (bez przechwytywania)? – Tracer

+0

Lambda to jakieś funkcje. W funkcjach masz dostęp do zmiennych globalnych, a także lambdas. Zmienne lokalne, na przykład w 'main()', nie są zmiennymi globalnymi, więc musisz bezpośrednio wskazać te zmienne zewnętrzne, których chcesz użyć. Może to ci pomaga. – Dakorn

9

Trzeba wrócić i zapytać siebie: Dlaczego lambdas zmienne przechwytywania w ogóle?

Lambdas może używać zmiennych z zewnętrznego zakresu. Jeśli jednak są to zmienne lokalne, wykraczają one poza zakres i nie można ich użyć po zwróceniu funkcji. Ale lambda może zostać wywołana po powrocie funkcji (lambda może zostać zwrócona z funkcji lub przechowywana w jakiejś globalnej lub instancji zmiennej itd.), A po powrocie funkcji nie może po prostu odnosić się bezpośrednio do zmiennych lokalnych, ponieważ już nie istnieją.

Dlatego lambdy mogą przechwytywać zmienne lokalne przez kopiowanie (skopiuj ich wartość w momencie utworzenia lambda). (Mogą również przechwytywać przez odniesienie, jako alternatywę dla kopii).

Powyższy problem istnieje tylko dla zmiennych o czasu automatycznego przechowywania. W przypadku zmiennych o statycznym czasie przechowywania (np. Zmiennych globalnych, statycznych zmiennych lokalnych) są one aktywne przez cały okres istnienia programu i nie ma problemu z dostępem do nich w dowolnym momencie.

0

Zgadzam się z komentarzem StoryTeller. Lubię to. Automatyczne przechwytywanie C++ globalnego var.

int x = 4; 

int main() 
{ 
    cout << "::x = " << ::x << endl; 

    [](int a){ ::x = a; }(2); 

    cout << "::x = " << ::x << endl; 

    return 0; 
} 

wyjściowa:

::x = 4 
::x = 2 
+2

Czy możesz wskazać, jakie nowe informacje (które jeszcze nie istnieją) zostały dodane wraz z odpowiedzią. – Ziezi

Powiązane problemy