std::mem_fn în C++

Transformă un pointer la metodă sau la câmp într-o funcție obișnuită care primește obiectul ca argument.

Sintaxă
#include <functional>
template<class M, class T>
constexpr auto mem_fn(M T::* pm) noexcept;

Ce face std::mem_fn

std::mem_fn(&Clasa::metoda) returnează un obiect apelabil: f(obiect, argumente) apelează obiect.metoda(argumente). Obiectul poate fi dat și ca pointer sau pointer inteligent.

Este util cu algoritmi care cer o funcție cu un singur parametru (elementul), de exemplu std::transform sau std::for_each. Funcționează și cu câmpuri: std::mem_fn(&Clasa::camp) returnează valoarea câmpului.

Parametri

Parametru Descriere
pm Pointerul la metodă sau la câmp (&Clasa::nume).

Ce returnează

Un obiect apelabil care primește obiectul ca prim argument.

Exemple

Exemplul 1: Metoda fiecărui element dintr-un vector

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

struct Angajat {
    std::string nume;
    double salariu;
    double anual() const { return salariu * 12; }
};

int main() {
    std::vector<Angajat> echipa{{"Ana", 7000}, {"Mihai", 6500}};

    std::vector<double> anuale(echipa.size());
    std::transform(echipa.begin(), echipa.end(), anuale.begin(), std::mem_fn(&Angajat::anual));
    std::println("{}", anuale);

    auto nume = std::mem_fn(&Angajat::nume);
    std::println("{}", nume(echipa[1]));
}

Rezultat

[84000, 78000]
Mihai

Greșeli frecvente

  • Dai lui mem_fn numele metodei fără & și fără clasă (std::mem_fn(anual)). Trebuie pointerul la membru: std::mem_fn(&Angajat::anual).

Comenzi înrudite

  • std::invoke: Apelează orice lucru apelabil cu argumentele date, inclusiv pointeri la metode și la membri.
  • std::bind_front: Fixează primele argumente ale unei funcții și returnează o funcție care le primește doar pe restul.
  • std::transform: Aplică o funcție fiecărui element și scrie rezultatele în alt interval (sau în același).
  • std::function: Variabilă care poate ține orice funcție, lambda sau obiect apelabil cu o anumită semnătură.