2015-08-13 13 views
9

Czy ktoś proszę mi pokazać przykłady następujące:C++ 11 lambda: mieszany lista przechwytywania

1) Lambda, który przechwytuje x przez wartość. y przez odniesienie. Do czego pozostała wartość domyślna, jeśli nie jest określona?

2) Lambda, która przechwytuje wartość x. y przez odniesienie, wszystko inne według wartości.

3) Lambda, która przechwytuje wartość x. y przez odniesienie, wszystkie inne przez odniesienie.

Również Dopuszczalne jest 2 lambda w tym samym zakresie mieć tej samej sygnatury wychwytywania, jak oba być [] lub być zarówno [& x, =]

Dzięki

Odpowiedz

8

1) [x, &y](){} reszta nie jest zrobione

2) [=, &y](){}

3) [&, x](){}

wychwytywanie-lista jest listą oddzielonych zero lub większą liczbą wychwytów, ewentualnie beginni ng z ustawieniem domyślnym przechwytywania. Jedyne wartości domyślne to (odniesienie) i = (według wartości). Jeśli używany jest domyślny przechwytywania , żadne inne przechwyty nie mogą korzystać z tego samego typu przechwytywania. Każde przechwycenie może pojawić się tylko raz.

Również Dopuszczalne jest 2 lambda w tym samym zakresie mieć tej samej sygnatury przechwytywania takich jak być zarówno [], lub oba na [& x, =]

Oczywiście jest dozwolony.Każda lambda będzie odrębnym obiektem i ma swój odrębny typ. Jeśli przechwycisz zmienną po wartości w dwóch lambdach, to każda lambda będzie miała swoją kopię. Jeśli przechwycisz zmienną przez odniesienie w dwóch lambdach, to każda lambda będzie miała odniesienie do tej samej przechwyconej zmiennej.

2

1)

[x,&y](){} // the rest is not captured, eg `z` is not defined in the scope 

2)

[=,&y](){} // `=` is capture everything by value 

3)

[&,x](){} // `&` is capture everything by reference 
7

można po prostu napisać kilka przykładów:

int x = 7, y = 12, z = 24; 

auto lambda1 = [x, &y]{ 
    // can't do this... 
    // std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl; 
    std::cout << "x=" << x << ", y=" << y << std::endl; 
}; 

auto lambda2 = [=, x, &y]{ 
    std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl; 
}; 

auto lambda3 = [&, x, &y]{ 
    std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl; 
}; 

++x, ++y, ++z; 
lambda1(); 
lambda2(); 
lambda3(); 

Teraz lambda1 tutaj nie można użyć z. Nie ma żadnego "niejawnego" przechwytywania, ponieważ nie mamy określonego = lub & określonego, a z nie pojawia się na liście przechwytywania, nie możemy wydrukować tam z. Jest to błąd, jeśli spróbujemy użyć linii, którą skomentowałem.

Pozostałe dwie części są w porządku i zostaną wydrukowane odpowiednio 7, 13, 24 i 7, 13, 25. Zauważ, że = i & muszą być na pierwszym miejscu. Ponadto, biorąc pod uwagę, że mamy do przechwytywania wszystkim wartości/odniesienia, jeden z pozostałych przechwytuje jest zbędna, więc mogliśmy zrobiłeś:

auto lambda2 = [=, &y]{ ... }; 
auto lambda3 = [&, x]{ ... }; 
+0

Oryginalne 'lambda2' i' lambda3' nie powinny się kompilować. Po określeniu domyślnego przechwytywania pozostałe jawne przechwytywania nie mogą określać tego samego trybu. – Praetorian

+0

@ Lista przechwytywania w koszach, jak [&, x, & y] lub [=, x, & y] jest nieprawidłowa. Ponieważ: jeśli używane jest domyślne ustawienie przechwytywania, żadne inne przechwytywania nie mogą używać tego samego typu przechwytywania: –

+0

@ Barry, czy możesz odpowiedzieć na komentarz Elohim Meth? Co to znaczy "domyślne przechwytywanie"? Jakie znaczenie ma "pozostałe jawne przechwytywania nie mogą określać tego samego trybu"? –

1

Cytując Bjarne od swoich C++11 FAQ:

Sieć [&] jest „lista capture”, określając, że lokalne nazwy stosowane będą przekazywane przez referencję. Moglibyśmy powiedzieć, że chcieliśmy "uchwycić" tylko v, moglibyśmy to powiedzieć: [& v]. Gdybyśmy chcieli przekazać v według wartości, moglibyśmy powiedzieć: [= v]. Capture nic to [], przechwytuj wszystko za pomocą odnośników jest [&], a przechwytywanie wszystkich według wartości to [=]. Jeśli działanie nie jest ani pospolite, ani proste, zaleca się użycie nazwanego obiektu funkcji lub funkcji.

Powiązane problemy