Ce face std::invoke
Pentru o funcție sau o lambda, std::invoke(f, a, b) este la fel ca f(a, b). Diferența apare la pointerii la membri: std::invoke(&Clasa::metoda, obiect, a) apelează obiect.metoda(a), iar std::invoke(&Clasa::camp, obiect) returnează obiect.camp.
Se folosește în cod generic, care primește „ceva apelabil” de la utilizator și trebuie să funcționeze cu toate formele. Algoritmii din std::ranges folosesc std::invoke pentru proiecții.
Parametri
| Parametru | Descriere |
|---|---|
f |
Funcția, lambda, obiectul apelabil sau pointerul la membru. |
argumente |
Argumentele; la pointerii la membri, primul este obiectul. |
Ce returnează
Rezultatul apelului.
Exemple
Exemplul 1: Funcții, metode și câmpuri
#include <functional>
#include <print>
#include <string>
struct Produs {
std::string nume;
double pret;
double cuReducere(double procent) const { return pret * (1 - procent / 100); }
};
int dublu(int x) { return 2 * x; }
int main() {
Produs p{"Laptop", 3000};
std::println("{}", std::invoke(dublu, 21));
std::println("{}", std::invoke(&Produs::cuReducere, p, 10));
std::println("{}", std::invoke(&Produs::nume, p));
}
Rezultat
42
2700
Laptop
Exemplul 2: O funcție generică
aplicaTuturor acceptă și o lambda, și un pointer la câmp.
#include <functional>
#include <print>
#include <string>
#include <vector>
struct Elev { std::string nume; double medie; };
template <class F>
void aplicaTuturor(const std::vector<Elev>& elevi, F f) {
for (const auto& e : elevi) {
std::print("{} ", std::invoke(f, e));
}
std::println();
}
int main() {
std::vector<Elev> elevi{{"Ana", 9.5}, {"Dan", 8.25}};
aplicaTuturor(elevi, &Elev::nume);
aplicaTuturor(elevi, [](const Elev& e) { return e.medie >= 9; });
}
Rezultat
Ana Dan
true false
Greșeli frecvente
- Încerci să apelezi un pointer la metodă direct:
(&Produs::cuReducere)(p, 10). Nu compilează; sintaxa corectă este(p.*ptr)(10)sau, mai simplu,std::invoke(ptr, p, 10).
Comenzi înrudite
std::function: Variabilă care poate ține orice funcție, lambda sau obiect apelabil cu o anumită semnătură.std::mem_fn: Transformă un pointer la metodă sau la câmp într-o funcție obișnuită care primește obiectul ca argument.std::bind: Creează o funcție nouă dintr-una existentă, fixând unele argumente sau schimbându-le ordinea.