2013-08-11 19 views
5

Powodem wyrażeń lambda jest niejawnie generowanie obiektów funkcji w "bardziej wygodny sposób". Jak widać na poniższym przykładzie, jest nie tylko mniej wygodna i dłuższa, ale ma również mylącą składnię i notację.Jaka jest zaleta "wyrażeń lambda"?

Czy istnieje jakiś sposób wykorzystania tego kodu, który sprawia, że ​​kod jest bardziej czytelny?

cout << count(vec, [&](int a){ return a < x; }) << endl; // lambda 
cout << count(vec, Less_than<int> (x)) << endl;   // normal functor def-n 
+3

Wersja lambda nie jest dłuższa. Nie-lambda jest niekompletna, ponieważ nie mamy definicji "Less_than". –

+0

Jak to jest, że 'Less_than (x)' a "normalna definicja funkcji" ?? Sądząc po twoim pierwszym przykładzie, wygląda na to, że musisz związać wartość 'x' z dwufunkcyjnym funktorem komparatora, konwertując go do komparatora jednoparametrowego. To już funkcjonalność, która wykracza znacznie poza "normalną definicję funkcji". – AnT

Odpowiedz

10

To jest bardziej czytelny, ponieważ stawia realizację funkcji w prawo w miejscu, gdzie jest on nazywany, utrzymując w ten sposób naturalną górną do dołu przepływ kodu niezmienionej.

Widzisz, zwykłe funkcje mają swoje wady i zalety. Z jednej strony funkcje pomagają zredukować liczbę powtórzeń w kodzie, dzięki czemu kod jest bardziej uporządkowany i czytelniejszy. Z drugiej strony funkcje przerywają naturalny przepływ kodu i przenoszą kontrolę do zupełnie innej lokalizacji. Może to zmniejszyć czytelność z raczej oczywistych powodów: jest to jak czytanie książki, która jest wypełniona zagnieżdżonymi odniesieniami do przodu i do tyłu.

Aby więc właściwie wykorzystać właściwości zwykłych funkcji, należy ich użyć do realizacji przemyślanych, kompletnych i odizolowanych abstrakcji. W ten sposób zwykłe funkcje poprawią czytelność kodu.

Jednak w przypadku małych "jednorazowych" jednorazowych kodów narzędzi zwykłe funkcje nie działają tak dobrze. Dzięki nim kod jest znacznie mniej czytelny. To tutaj pojawiają się funkcje lambda. Umożliwiają one wprowadzenie jednorazowego kodu użytkowego bezpośrednio w miejsce połączenia, tam, gdzie jest to konieczne.

+0

Dodatkowym punktem jest to, że funkcje lambda mogą bezpośrednio uzyskiwać dostęp do zmiennych, które znajdują się w zakresie w kontekście macierzystym (w tym przypadku, lambda może uzyskać bezpośredni dostęp do "vec", jeśli to konieczne, na przykład.) Jest to część użyteczności polegającej na tym, że nie trzeba stworzyć osobną funkcję. –

1

Wyrażenie lambda istnieje w celu uproszczenia kodu. To:

auto fun = []() { return; }; 

Czy zastąpiony przez kompilator z:

// Namespace scope 
struct __lambda_1 { 
    void operator()() { return; } 
}; 

// local scope 
__lambda_1 fun{}; 

To jest główną motywacją do składni lambda: Aby zastąpić tradycyjny funkcja obiektów z łatwiejsze do odczytania funkcję anonimową zadeklarowanej w miejscu, gdzie jest potrzebna, zamiast mieć oddzielny obiekt funkcji, który musi być zadeklarowany w innym zakresie. Nie chodzi tylko o zastąpienie nazwanych obiektów funkcji.

Rzeczywiście, biblioteka standardowa zawiera wiele nazwanych obiektów funkcji, takich jak std::unary_function i rzeczy takie jak std::less. Jednak obiekty te mają ograniczoną użyteczność i nie mogą przejąć każdej potencjalnej roli, jaką mogłaby osiągnąć lambda.

Tak, może sprawić, że kod będzie znacznie bardziej czytelny, umieszczając kod, którego standardowa biblioteka nie zapewnia dokładnie tam, gdzie jest to wymagane, bez zanieczyszczania kodu dziesiątkami linii struct s i zanieczyszczania przestrzeni nazw nazwami " Prawdopodobnie użyjesz nie więcej niż raz lub dwa razy.

Powiązane problemy