===== Szablony generate i generate_n ===== Szablony ''generate'' i ''generate_n'' pozwalają przypisać wartości zwracane przez //generator// do elementów tablicy lub kontenera udostępniającego iterator. Są szczególnie przydatne wtedy, gdy kontener chcemy wypełnić zgodnie z jakąś zależnością funkcyjną. Można z nich również korzystać w celu przypisania kolejnym elementom losowych wartości.\\ Generatorem może być bezargumentowa funkcja lub //obiekt funkcyjny//((//obiekt funkcyjny//, //funktor// - obiekt udostępniający metodę ''operator()'')), zwracający obiekty takiego samego typu, jak przechowywane w kontenerze. ===== generate ===== ==== Deklaracja ==== #include // tu jest definicja szablonów generate i generate_n template void generate ( ForwardIterator first, ForwardIterator last, Generator gen ) ==== Działanie ==== ''generate'' przypisuje wartość zwracaną przez kolejne wywołania ''gen'' począwszy od elementu ''first'' (włącznie z ''first'') skończywszy na ''last'' (bez ''last''). Pozwala więc w intuicyjny sposób przypisać wartości elementom należącym do kontenera. ==== Parametry ==== * ''first'' - iterator pierwszego elementu kontenera * ''last'' - iterator elementu za ostatnim w kontenerze * ''gen'' - bezargumentowa funkcja lub funktor zwracająca obiekty typu przechowywanego przez kontener; wartość zwracana przez jej kolejne wywołania jest przypisywana kolejnym elementom. ==== Krótki przykład ==== /* Wypełnia wektor "losowymi" wartościami */ int random() { return 4; } //patrz http://www.metasploit.com/users/hdm/tools/debian-openssl/ const size_t size = 3; vector v = vector(size); generate(v.begin(), v.end(), random); ===== generate_n ===== ==== Deklaracja ==== #include // tu jest definicja szablonów generate i generate_n template void generate_n ( OutputIterator first, Size n, Generator gen ) ==== Działanie ==== ''generate_n'' przypisuje wartość zwracaną przez kolejne wywołania ''gen'' począwszy od elementu ''first'' (włącznie z ''first'') dla ''n'' kolejnych elementów. ==== Parametry ==== * ''first'' - iterator pierwszego elementu kontenera * ''n'' - ilość kolejnych elementów do przypisania * ''gen'' - bezargumentowa funkcja lub funktor zwracająca obiekty typu przechowywanego przez kontener; wartość zwracana przez jej kolejne wywołania jest przypisywana kolejnym elementom. ==== Krótki przykład ==== /* Wypisuje "losowe" wartości na stdout */ int random() { return 9; } const size_t size = 3; generate_n(ostream_iterator(cout, " "), size, random); ===== Porównanie ===== Wydawać by się mogło, że szablony ''generate'' i ''generate_n'' w gruncie rzeczy robią to samo, więc są redundantne. Przecież wywołanie: generate_n (first, n, gen) można zastąpić przez: generate (first, first+n, gen) Jednak w funkcjach tych występują inne wymagania co do iteratora. Do wywołania ''generate'' potrzebny jest iterator wskazujący na koniec kontenera. A może się zdarzyć, że: * zwrócenie takiego iteratora jest kosztowne, szczególnie gdy potrzebujemy nie koniec, a na przykład połowę kolekcji; * otrzymanie takiego iteratora jest niemożliwe. Przykładowo takiej operacji (patrz {{:stl_algorytmy:generate2.cpp}}): generate_n(ostream_iterator(os, " "), 10, ga.rig_) za pomocą ''generate'' wykonać się nie da. ===== Długi przykład ===== //Długi// przykład zastosowania algorytmu dotyczy pewnego szkieletu algorytmu genetycznego, a dokładniej generacji populacji początkowej.\\ Kolorowy kod programu znajduje się [[generate_kod|tutaj]]. To samo w postaci pliku źródłowego: {{:stl_algorytmy:generate2.cpp}} ===== Podsumowanie ===== Szablony ''generate'' i ''generate_n'' umożliwiają łatwe wypełnianie kolekcji wartościami zwracanymi przez funkcje lub funktory. Są przydatne tam, gdzie wartości początkowe elementów kontenera zależą od stanu generatora.