===== 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.