2012-09-04 10 views
10

Witam mam znaleźć ten kod w dokumentacji systemu WindowsC++ [b] operator

ale ja nie rozumiem co oznacza

[&] 

tylko proszę można wyczyścić mi, co należy zrobić ??

to nie jest C++ standardowe prawda?

Jest to kod:

void parallel_matrix_multiply(double** m1, double** m2, double** result, size_t size) 
{ 
    parallel_for (size_t(0), size, [&](size_t i) 
    { 
     for (size_t j = 0; j < size; j++) 
     { 
     double temp = 0; 
     for (int k = 0; k < size; k++) 
     { 
      temp += m1[i][k] * m2[k][j]; 
     } 
     result[i][j] = temp; 
     } 
    }); 
} 

Odpowiedz

16

Jest to funkcja C++ 11 i jest nazywana klauzulą ​​przechwytywania lambda . W tym przypadku [&] udostępnia funkcję lambda wszystkie argumenty funkcji parallel_matrix_multiply() przez odniesienie.

Aby uzyskać więcej informacji, patrz lambda functions.

+0

"udostępnia wszystkie argumenty funkcji' parallel_matrix_multiply() 'przez odniesienie do funkcji lambda"? –

+1

@SteveJessop, '[&]' czyni wszystkie zmienne w zakresie dostępnym w ciele funkcji lambda przez odniesienie, włączając w to argumenty funkcji 'parallel_matrix_multiply()'.Czy jest to błędne, czy tylko myląco sformułowane? – hmjd

+0

To prawda (o ile rozumiem: nie wiem, czy są jakieś mylące przypadki). Moja uwaga była po prostu próbą uczynienia zdania nieco mniej nieporęcznego, przepraszam, jeśli nie przekazałem tego. –

4

Jest to funkcja lambda, C++ 11 cechą

[&](size_t i){...} 

będzie działać jak zwrotnego lub funktora. Nie musisz więc pisać innej funkcji gdzieś indziej, aby przejść do parallel_for.

12

Wprowadza wyrażenie lambda. Zawartość kwadratowych nawiasów wskazuje, co ma być przechwycone wewnątrz lambda. Mając tylko & oznacza to, że wszystko, co jest wymienione wewnątrz lambda i można znaleźć poza jego zasięgiem, jest przechwytywane przez odniesienie.

przykład:

int a = 0; 
auto l = [&]() { 
    ++a; // a refers to the a outside of this scope through a reference 
} 
l(); // execute the lambda 
+0

to jest ładny przykład ... podoba mi się komentarz wewnątrz funkcji, który sprawia, że ​​jest on bardziej czytelny w rozumieniu –

+0

Więc jeśli piszę [=] i edytuję zmienną, to w funkcji lambda zmieni się wartość? czy to nie dlatego, że nie przeszedł przez referencję? –

+0

@frank: jeśli po prostu zmienisz & to = nie skompiluje się, ponieważ nie możesz zmutować skopiowanych zmiennych, chyba że wyraźnie powiesz, że zamierzasz to zrobić za pomocą zmiennego słowa kluczowego. – sellibitze

5

Jest to punkt wychwytywania stosuje się do wyrażenia lambda. Wyrażenie lambda może mieć dostęp do wszystkich zmiennych obejmującego jego zakres (tj. Jeśli lambda znajduje się w funkcji, może ona mieć dostęp do wszystkich zmiennych w tej funkcji). [&] oznacza, że ​​lambda otrzyma wszystkie zmienne przez odniesienie. Można je również pobrać według wartości, w takim przypadku można użyć [=]. można również określić zmienne betonowe, które muszą być podjęte w określony sposób, na przykład ten kod:

[&X, =] 

oznacza, że ​​lambda odbędzie zmienną X przez odniesienie, a wszyscy inni przez wartość.

+0

Więc jeśli piszę [=] i edytuję zmienną .... to czy funkcja lambda zmienia wartość? Przypuszczam, że nie .. prawda? –

+0

@frank, tak, jeśli napiszesz [=], wartość poza lambdą pozostanie taka sama, bez względu na to, co zrobisz. – SingerOfTheFall

+0

Jest to równoznaczne z przekazywaniem zmiennej według wartości do zwykłej funkcji: kopia dzwoniącego się nie zmienia. Możesz to łatwo sprawdzić za pomocą przykładu zabawkowego. – Useless

5

[&] oznacza, że ​​będziesz mieć dostęp do zmiennych z otaczającego kodu wewnątrz wyrażenia lambda, i będzie to dostęp przez referenc (tj. Możesz je modyfikować). W przykładowym kodzie widać, że m1, m2, result i są używane w experssionie lambda, mimo że nie są przekazywane jako parametry.

+2

Technicznie nie można modyfikować zmiennych w żaden sposób, ponieważ lambdy, które nie są wyraźnie określone jako "zmienne", mają 'const'' operator() ', więc przechwyconych zmiennych nie można zmienić. Dla 'mutable' lambda zmienne mogą być zmienione w obu przypadkach, jednak zmiana jest widoczna poza lambdą tylko do przechwytywania przez odniesienie – Grizzly