std::generate în C++

Completează un interval cu valorile returnate de apeluri succesive ale unei funcții.

Sintaxă
void generate(ForwardIt first, ForwardIt last, Generator g);

Ce face std::generate

std::generate apelează funcția g (fără argumente) pentru fiecare poziție și pune acolo rezultatul. Spre deosebire de std::fill, fiecare element poate primi altă valoare.

Funcția este de obicei o lambda care își păstrează starea între apeluri (cu mutable sau prin captură prin referință), sau un generator de numere aleatorii. Există și std::generate_n.

Parametri

Parametru Descriere
first, last Intervalul completat.
g Funcție fără argumente, apelată o dată pentru fiecare element.

Ce returnează

Nimic.

Exemple

Exemplul 1: Puterile lui 2

Lambda mutable își modifică propria copie a lui p la fiecare apel.

#include <algorithm>
#include <print>
#include <vector>

int main() {
    std::vector<int> puteri(8);
    std::generate(puteri.begin(), puteri.end(), [p = 1]() mutable {
        int curent = p;
        p *= 2;
        return curent;
    });
    std::println("{}", puteri);
}

Rezultat

[1, 2, 4, 8, 16, 32, 64, 128]

Exemplul 2: Numere de bon fiscal

#include <algorithm>
#include <print>
#include <string>
#include <vector>

int main() {
    int urmatorul = 1041;
    std::vector<std::string> bonuri(4);

    std::ranges::generate(bonuri, [&urmatorul] { return "BF-" + std::to_string(urmatorul++); });
    std::println("{}", bonuri);
}

Rezultat

["BF-1041", "BF-1042", "BF-1043", "BF-1044"]

Greșeli frecvente

  • Pui o lambda fără mutable care încearcă să-și modifice captura prin valoare: nu compilează. Adaugă mutable sau capturează prin referință.

Comenzi înrudite

  • std::fill: Atribuie aceeași valoare tuturor elementelor unui interval (fill) sau primelor n elemente (fill_n).
  • std::iota: Completează un interval cu valori consecutive: valoare, valoare + 1, valoare + 2…
  • std::mt19937: Generatorul Mersenne Twister: numere pseudo-aleatorii rapide și de calitate, reproductibile cu un seed fix.