find_if + lambda C++0x

Wspominałem nie tak dawno o szukaniu w STLowych kontenerach za pomocą funkcji find_if. Przedstawiłem tam kilka sposób wykorzystania tego algorytmu i prosty funktorów na bazie bibliotek STL i boost.

Dzięki nadchodzącemu wielkimi krokami nowemu standardowi C++0x, pisanie prostych predykatów stanie się wkrótce jeszcze prostsze dzięki funkcjom i wyrażeniom lambda.

Nie trzeba będzie pisać prostych funktorów, które nieraz nie mogły znajdować się w pobliżu wykorzystania, przez niemożliwość zdefiniowania szablonowej klasy wewnątrz funkcji lub metody, przez co trochę uciążliwe było ich używanie. A definiowanie ich w oddalonych miejscach kodu nieraz sprawiało trudności w zrozumieniu kodu, czy zaburzało przepływ kodu.

Dzięki lambda będzie można w miejscu wywołania zdefiniować cała kwintesencje działania predykatu, co dla prostych działań stanie się bardzo użyteczne.

Wszelkie poniższe przykłady będą wykorzystywać struktury zdefiniowanej w notce find_if predicate.

Wyszukiwanie elementu w kontenerze z zastosowaniem postaci funkcyjnej lambda wyglądałoby tak:

MyObjVector::iterator it = std::find_if(my_vector.begin(), my_vector.end(),
	[] (const MyObjVector::value_type& obj) -> bool { return obj.name == "foo"; } );

Trochę nieco rozległe sie to wydaje.

Przy zastosowaniu wyrażeń lambda mogłoby to wyglądać następująco:

MyObjVector::iterator it = std::find_if(my_vector.begin(), my_vector.end(),
	[] (const MyObjVector::value_type& obj) (obj.name == "foo") );

Choć nie jestem pewien do końca czy jest to poprawne, aczkolwiek typ zwracany przez funkcje lambda jest typem wyrażenia. Postać wyrażeniowa jest bardzo użyteczna dla małych wyrażeniowych operacji, jest ona ograniczona do pojedynczego wyrażenia.

Może nieco lepszym rozwiązaniem byłoby dorzucić do struktury MyObj operatora porównania z std::string lub inlineowej metody tego dokonującej:

bool IsName(const std::string& str) const {
	return name == str;
}

I zastosowanie tej metody w wyrażeniu lambda:

[] (const MyObj& obj) (obj.IsName("foo"));

Jak widać lambda będzie zbawieniem w niektórych zastosowaniach i niektórzy nie mogą się już doczekać, ale jak wspomniałem w poprzedniej notce to już tuż tuż ;)

Kilka prostych przykładów wykorzystania nowych featursów, w tym lambda, można znaleźć w ostatniej notce na Visual C++ Team Blog: Lambdas, auto, and static_assert: C++0x Features in VC10, Part 1.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *