Narzędzia użytkownika

Narzędzia witryny


bind

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
bind [2008/04/12 19:24]
maciejp
bind [2008/04/14 08:48]
maciejp
Linia 1: Linia 1:
 ======Biblioteka Boost.Bind====== ======Biblioteka Boost.Bind======
  
-Funkcja boost::bind jest generalizacją funkcji std::​bind1st i std::​bind2nd dostępnych w bibliotece standardowej. Funkcja ta wspiera funktory, funkcje, wskaźniki do funkcji oraz wskaźniki do funkcji składowych. Jest w stanie związać dowolny argument ze specyficzną wartością albo przekierować argumenty wejściowe we wskazane pozycje. boost::bind nie nakłada żadnych wymagań obiektom funkcyjnym, w ogólności nie wymaga standardowych definicji typów takich jak: result_type,​ first_argument_type,​ second_argument_type. +Funkcja ​''​boost::bind'' ​jest generalizacją funkcji ​''​std::​bind1st'' ​''​std::​bind2nd'' ​dostępnych w bibliotece standardowej. Funkcja ta wspiera funktory, funkcje, wskaźniki do funkcji oraz wskaźniki do funkcji składowych. Jest w stanie związać dowolny argument ze specyficzną wartością albo przekierować argumenty wejściowe we wskazane pozycje. ​''​boost::bind'' ​nie nakłada żadnych wymagań obiektom funkcyjnym, w ogólności nie wymaga standardowych definicji typów takich jak: ''​result_type''​''​first_argument_type''​''​second_argument_type''​
-Do korzystania z funcji boost::bind konieczne jest dołączenie nagłówka ​boost/​bind.hpp. +Do korzystania z funcji boost::bind konieczne jest dołączenie nagłówka ​''​boost/​bind.hpp''​.
- +
- +
  
  
Linia 36: Linia 33:
 int main() { int main() {
   int i1=1,​i2=2,​i3=3,​i4=4,​i5=5,​i6=6,​i7=7,​i8=8,​i9=9;​   int i1=1,​i2=2,​i3=3,​i4=4,​i5=5,​i6=6,​i7=7,​i8=8,​i9=9;​
-  ​(boost::​bind(&​nine_arguments,​_9,​_2,​_1,​_6,​_3,​_8,​_4,​_5,​_7))  ​//​utworzenie tymczasowego funktora i wywołanie +  boost::​bind(f,​_9,​_2,​_1,​_6,​_3,​_8,​_4,​_5,​_7) ​          ​//​utworzenie tymczasowego funktora i wywołanie 
-    (i1,​i2,​i3,​i4,​i5,​i6,​i7,​i8,​i9); ​                           //​odpowiadające wywołaniu f(i9, i2, i1, i6, i3, i8, i4, i5, i7) +    (i1,​i2,​i3,​i4,​i5,​i6,​i7,​i8,​i9); ​                    ​//​odpowiadające wywołaniu f(i9, i2, i1, i6, i3, i8, i4, i5, i7) 
-                                                             ​//w wyniku otrzymamy ciąg: 921638457 +                                                      //w wyniku otrzymamy ciąg: 921638457 
-+  ​return ​0; 
-bind(f, _2, _3, _1, _1, 0, 0, _3, 0, _2)(x, y, z) //​utworzenie tymczasowego funktora i wywołanie +}                                               
-                                                    +
 </​code>​ </​code>​
  
 Realizujemy to za pomocą symbli zastępczych oznaczanych jako _1, _2, ..., _9. Dostępnych mamy łacznie 9 takich symboli. Ogranicza to możliwośc tworzenia funktorów do funktorów 9 elementowych (w przypadku funkcji składowych jest to 8 argumentów;​ musimy pamietć o przekazaniu obiektu na rzecz, którego będzie wywoływany funktor). Symbol _1 oznacza "​zastąp przez pierwszy argument wejściowy",​ analogicznie pozostałe osiem. Realizujemy to za pomocą symbli zastępczych oznaczanych jako _1, _2, ..., _9. Dostępnych mamy łacznie 9 takich symboli. Ogranicza to możliwośc tworzenia funktorów do funktorów 9 elementowych (w przypadku funkcji składowych jest to 8 argumentów;​ musimy pamietć o przekazaniu obiektu na rzecz, którego będzie wywoływany funktor). Symbol _1 oznacza "​zastąp przez pierwszy argument wejściowy",​ analogicznie pozostałe osiem.
-Jak wynika z przykładu, ​można dowolnie ​"​mieszać" argumenty ​ze stałymi jak i ich kolejność.+Argumenty ​można dowolnie ​zamieniać ze stałymi jak i zamieniać ​ich kolejność. 
  
 =====Użycie z funktorami===== =====Użycie z funktorami=====
  
-boost::bind nie jest ograniczony tylko do funkcji, akceptuje min. również funktory. W przypadku użycia funktora zazwyczaj ​trzeba ​jawnie podać typ zwracany przez operator() funktora (ewentualnie zdefinjować typ result_type w funktorze).+boost::bind nie jest ograniczony tylko do wskaźników ​do funkcji, akceptuje min. również funktory. W przypadku użycia funktora zazwyczaj ​należy ​jawnie podać typ zwracany przez operator() funktora (ewentualnie zdefinjować typ result_type w funktorze).
  
 <code cpp> <code cpp>
Linia 70: Linia 67:
 boost::​bind(boost::​type<​int>​(),​ f, _1, _1)(x); boost::​bind(boost::​type<​int>​(),​ f, _1, _1)(x);
 </​code>​ </​code>​
 +
 +
  
  
 =====Użycie ze wskaźnikami do składowych===== =====Użycie ze wskaźnikami do składowych=====
  
-Wskaźniki do metod i danych sładowych nie są obiektami funkcyjnymi,​ ponieważ nie wspierają operatora operator(). Dla wygody boost::bind akceptuje te wskażniki jako pierwszy argument. boost::bind używa funkcji boost::​mem_fn do przekonwertowania ​wskźników do składowych na funktory. Innymi słowy, wyrażenie:+Wskaźniki do metod i danych sładowych nie są obiektami funkcyjnymi,​ ponieważ nie wspierają operatora operator(). Dla wygody boost::bind akceptuje te wskażniki jako pierwszy argument. boost::bind używa funkcji boost::​mem_fn do konwersji ​wskźników do składowych na funktory. Innymi słowami, wyrażenie:
  
 <code cpp> <code cpp>
Linia 106: Linia 105:
 </​code>​ </​code>​
  
-Jako drugi argument boost::bind przekazujemy obiekt klasy na rzecz, której ma być wywoływana funkcja (jest to oczywiste, jeśli zauważymy, że pierwszym niejawnym argumentem metod jest zawsze wskaźnik this - adres obiektu). Najciekawsze są dwie ostatnie linijki przykładu. bind(&​Foo::​f,​ x, _1) przechowuje wewnętrzną kopję obieku x (warto zwrócić na to uwagę, szczególnie gdy kopjowanie obiektu jest kosztowne), natomiast bind(&​Foo::​f,​ p, _1) kopję wskażnika p (p jest sprytnym wskaźnikiem shared_ptr<>​),​ tworzony obiekt funkcyjny przechowuje swoją referencję do instancji klasy Foo i będzie ona poprawna nawet kiedy p wyjdzie poza zasięg lub wykonamy na p reset().+Jako drugi argument boost::bind przekazujemy obiekt klasy na rzecz, której ma być wywoływana funkcja (jest to oczywiste, jeśli zauważymy, że pierwszym niejawnym argumentem metod jest zawsze wskaźnik this - adres obiektu). Najciekawsze są dwie ostatnie linijki przykładu. ​''​bind(&​Foo::​f,​ x, _1)'' ​przechowuje wewnętrzną kopję obieku ​''​x'' ​(warto zwrócić na to uwagę, szczególnie gdy kopjowanie obiektu jest kosztowne), natomiast ​''​bind(&​Foo::​f,​ p, _1)'' ​kopję wskażnika ​''​p'' ​(''​p'' ​jest sprytnym wskaźnikiem ​''​shared_ptr<>​''​), tworzony obiekt funkcyjny przechowuje swoją referencję do instancji klasy Foo i będzie ona poprawna nawet kiedy p wyjdzie poza zasięg lub wykonamy na ''​p reset()''​.
  
-Funcję boost::bind można też bezprolemowo użyć z funkcjami wirtualnymi.+Funcję ​''​boost::bind'' ​można też bezprolemowo użyć z funkcjami wirtualnymi.
  
 <code cpp> <code cpp>
Linia 131: Linia 130:
   base* bp = &d;   base* bp = &d;
  
-boost::​bind(&​base::​print,​ _1)(b); +  ​boost::​bind(&​base::​print,​ _1)(b); 
-boost::​bind(&​base::​print,​ _1)(bp); +  boost::​bind(&​base::​print,​ _1)(bp); 
-boost::​bind(&​base::​print,​ _1)(d);+  boost::​bind(&​base::​print,​ _1)(d); 
 + 
 +  return 0; 
 +}
 </​code>​ </​code>​
  
Linia 213: Linia 215:
 =====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ęzy innymi przechowywć wcześniej utworzone fukntory ​lub przekazywać je jako argument do konstruktorówfunkcji. 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 222: Linia 224:
  
 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=====
Linia 233: Linia 234:
 !bind(f, ...) !bind(f, ...)
 </​code>​ </​code>​
 +
 Jest ekwiwalentem Jest ekwiwalentem
 +
 <code cpp> <code cpp>
 bind(logical_not(),​ bind(f, ...)) bind(logical_not(),​ bind(f, ...))
 </​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
  
Linia 274: Linia 278:
  
  
-=====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.
Linia 317: Linia 322:
     statuses.end(),​     statuses.end(),​
     boost::​bind(&​status::​report,​ _1));     boost::​bind(&​status::​report,​ _1));
 +
 +  return 0;
 } }
 </​code>​ </​code>​
bind.txt · ostatnio zmienione: 2008/04/14 09:00 przez maciejp