Różnice między wybraną wersją a wersją aktualną.
Both sides previous revision Previous revision Next revision | Previous revision | ||
bind [2008/04/14 08:53] maciejp |
bind [2008/04/14 09:00] maciejp |
||
---|---|---|---|
Linia 148: | Linia 148: | ||
derived! | derived! | ||
</code> | </code> | ||
+ | |||
=====Użycie zagnieżdżeń do kompozycji fukcji===== | =====Użycie zagnieżdżeń do kompozycji fukcji===== | ||
- | Część argumentów przekazywanych bind może być zagnieżdżonymi wyrażeniami boost::bind. | + | Część argumentów przekazywanych bind może być zagnieżdżonymi wyrażeniami ''boost::bind''. |
<code cpp> | <code cpp> | ||
Linia 158: | Linia 159: | ||
</code> | </code> | ||
- | Wewnętrzne wyrażenia są ewaluowane w bliżej nie okreśłonej kolejności, ale przed wywołaniem funktora zewnętzrnego boost::bind. Odnosząc się do przykładu, kiedy utworzony funktor jest wywoływany z argumentem x, w pierwszej kolejności ewalowany jest bind(g, _1)(x), dając g(x), następnie bind(f, g(x))(x), dając finalny wynik w postaci wywołania f(g(x)). | + | Wewnętrzne wyrażenia są ewaluowane w bliżej nie okreśłonej kolejności, ale przed wywołaniem funktora zewnętzrnego ''boost::bind''. Odnosząc się do przykładu, kiedy utworzony funktor jest wywoływany z argumentem ''x'', w pierwszej kolejności ewalowany jest ''bind(g, _1)(x)'', dając ''g(x)'', następnie ''bind(f, g(x))(x)'', dając finalny wynik w postaci wywołania ''f(g(x))''. |
- | Ta cecha boost::bind może być bardzo dobrze zastosowana do kompozycji funkcji. | + | Ta cecha ''boost::bind'' może być bardzo dobrze zastosowana do kompozycji funkcji. |
- | Trzeba zaznaczyć, że pierwszy argument boost::bind (opakowywany obiekt funkcyjny) nie jest ewalowany, nawet wtedy, kiedy jest to obiekt funkcyjny produkowany przez zagnieżdżone wywołanie bind lub argument w postaci symbola zastępczego. Poniższy przykład nie będzie działał tak, jakbyśmy tego oczekiwali. | + | Trzeba zaznaczyć, że pierwszy argument ''boost::bind'' (opakowywany obiekt funkcyjny) nie jest ewalowany, nawet wtedy, kiedy jest to obiekt funkcyjny produkowany przez zagnieżdżone wywołanie ''bind'' lub argument w postaci symbola zastępczego. Poniższy przykład nie będzie działał tak, jakbyśmy tego oczekiwali. |
<code cpp> | <code cpp> | ||
Linia 172: | Linia 173: | ||
</code> | </code> | ||
- | Oczekiwany efekt uzyskamy korzystając z pomocniczego obiektu funkcyjnego apply (implementacja apply w boost/bind/apply.hpp), który podajemy jako pierwszy argument boost::bind. Poprzedni przykład powinien wyglądać następująco. | + | Oczekiwany efekt uzyskamy korzystając z pomocniczego obiektu funkcyjnego ''apply'' (implementacja ''apply'' w ''boost/bind/apply.hpp''), który podajemy jako pierwszy argument ''boost::bind''. Poprzedni przykład powinien wyglądać następująco. |
<code cpp> | <code cpp> | ||
Linia 182: | Linia 183: | ||
</code> | </code> | ||
- | Używając bind można komponować funkcje korzystając naraz z boost::bind i funkcji (algorytmów) z biblioteki standardowej. | + | Używając ''bind'' można komponować funkcje korzystając naraz z ''boost::bind'' i funkcji (algorytmów) z biblioteki standardowej. |
<code cpp> | <code cpp> | ||
Linia 214: | Linia 215: | ||
</code> | </code> | ||
- | Jak widać na przykładzie łatwo można tworzyć złożone predykaty. Często trzeba się jednak często zastanowić, czy stosować bardzo złożone wyrażenia. Utrudniają one późniejszą analizę kodu, często wręcz uniemożliwiają. Warto rozważyć w takich przypadkach zdefinjowanie funktora lub operatora operator() dla klasy. | + | Jak widać na przykładzie łatwo można tworzyć złożone predykaty. Często trzeba się jednak często zastanowić, czy stosować bardzo złożone wyrażenia. Utrudniają one późniejszą analizę kodu, często wręcz uniemożliwiają. Warto rozważyć w takich przypadkach zdefinjowanie funktora lub operatora ''operator()'' dla klasy. |
=====Użycie z biblioteką Boost.Function===== | =====Użycie z biblioteką Boost.Function===== | ||
- | Funktor zwracany przez boost::bind można przypisać do obiektu funkcyjnego boos::function. W ten sposób można między innymi przechowywć wcześniej utworzone fukntory jako zmienne i pola klasy albo przekazywać je jako argument do konstruktorów lub funkcji. Przypisania możemy dokonać wykłym operatorem =. | + | Funktor zwracany przez ''boost::bind'' można przypisać do obiektu funkcyjnego ''boos::function''. W ten sposób można między innymi przechowywć wcześniej utworzone fukntory jako zmienne i pola klasy albo przekazywać je jako argument do konstruktorów lub funkcji. Przypisania możemy dokonać wykłym operatorem ''=''. |
<code cpp> | <code cpp> | ||
Linia 226: | Linia 228: | ||
</code> | </code> | ||
- | Warunkiem poprawnej kompilacji jest dokładne określenie typu szablonu obiektu function (zasada działania boost::function wykracza poza ten artykuł). | + | Warunkiem poprawnej kompilacji jest dokładne określenie typu szablonu obiektu function (zasada działania ''boost::function'' wykracza poza ten artykuł). |
=====Przeciążone operatory===== | =====Przeciążone operatory===== | ||
- | Przeciązone operatory dla boost::bind pojawiły się w Boost 1.33 | + | Przeciązone operatory dla ''boost::bind'' pojawiły się w Boost 1.33 |
- | Obiekty funkcyjne produkowane przez boost::bind przeciążają logiczny operator przecenia ! oraz operatory relacji ==, !=, <, <=, >, >=. | + | Obiekty funkcyjne produkowane przez ''boost::bind'' przeciążają logiczny operator przecenia ''!'' oraz operatory relacji ''=='', ''!='', ''<'', ''<='', ''>'', ''>=''. |
<code> | <code> | ||
Linia 244: | Linia 247: | ||
</code> | </code> | ||
- | gdzie logical_not jest funktorem przyjmującym jeden argument x i zwracający !x. | + | gdzie ''logical_not'' jest funktorem przyjmującym jeden argument ''x'' i zwracający ''!x''. |
<code cpp> | <code cpp> | ||
bind(f, ...) op x | bind(f, ...) op x | ||
</code> | </code> | ||
- | op jest operatorem relacji, wyrażniu temu odpowiada | + | ''op'' jest operatorem relacji, wyrażniu temu odpowiada |
<code cpp> | <code cpp> | ||
bind(relation(), bind(f, ...), x) | bind(relation(), bind(f, ...), x) | ||
</code> | </code> | ||
- | gdzie relation jest funktorem przyjmującym dwa argumenty a i b i zwracającym a op b. | + | gdzie ''relation'' jest funktorem przyjmującym dwa argumenty ''a'' i ''b'' oraz zwracającym ''a op b''. |
- | Przeciążenie tych operatorów umożliwia na konwencjonalne negowanie wyniku boost::bind: | + | Przeciążenie tych operatorów umożliwia na konwencjonalne negowanie wyniku ''boost::bind'': |
<code cpp> | <code cpp> | ||
Linia 262: | Linia 265: | ||
</code> | </code> | ||
- | oraz na porównywanie wyników boost::bind z wartościami: | + | oraz na porównywanie wyników ''boost::bind'' z wartościami: |
<code cpp> | <code cpp> | ||
Linia 274: | Linia 277: | ||
</code> | </code> | ||
- | albo z innym wyrażeniem boost::bind: | + | albo z innym wyrażeniem ''boost::bind'': |
<code cpp> | <code cpp> | ||
std::sort(first, last, bind(&X::name, _1) < bind(&X::name, _2)); | std::sort(first, last, bind(&X::name, _1) < bind(&X::name, _2)); | ||
</code> | </code> | ||
+ | |||
Linia 284: | Linia 288: | ||
=====Inny przykład użycia===== | =====Inny przykład użycia===== | ||
- | boost::bind umożliwia w przeciwnieństwie do funkcji z biblioteki standardowej (służących do tworzenia adpterów funkcji) bardzo elastyczną pracę z kodem. | + | ''boost::bind'' umożliwia w przeciwnieństwie do funkcji z biblioteki standardowej (służących do tworzenia adpterów funkcji) bardzo elastyczną pracę z kodem. |
<code cpp> | <code cpp> | ||
Linia 344: | Linia 348: | ||
</code> | </code> | ||
- | Użycie funkcji standardowych (std::mem_fun_ref i std::mem_fun) zmusza do zmian także pętli for_each po każdej modyfikacji typu przechowywanego przez wektor, a nawet uniemożliwia dalszą pracę (brak obsługi w przypadku użycia sprytnych wskaźników). | + | Użycie funkcji standardowych (''std::mem_fun_ref'' i ''std::mem_fun'') zmusza do zmian także pętli ''for_each'' po każdej modyfikacji typu przechowywanego przez wektor, a nawet uniemożliwia dalszą pracę (brak obsługi w przypadku użycia sprytnych wskaźników).\\ |
+ | \\ | ||
+ | \\ | ||
+ | --- //[[mplachta@stud.elka.pw.edu.pl|Maciej Płachta H1ISI]]// |