0Pricing
C++ Academy · Lezione

std::function

Memorizzare qualsiasi callable

std::function è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.

Che cos'è std::function?

std::function è un wrapper con type erasure che può contenere qualsiasi oggetto chiamabile compatibile con una determinata firma: funzioni libere, lambda, functor o espressioni con argomenti associati.

  • Viene dichiarato con la firma di destinazione.
  • È definito in <functional>.
#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    std::function<int(int, int)> f = add;
    std::cout << f(2, 3) << '\n';
    return 0;
}

Memorizzare una lambda

A differenza di un puntatore a funzione grezzo, std::function memorizza senza problemi una lambda, anche se contiene catture.

#include <iostream>
#include <functional>

int main() {
    int offset = 10;
    std::function<int(int)> f = [offset](int x) { return x + offset; };
    std::cout << f(5) << '\n';
    return 0;
}

Memorizzare un functor

Un functor è un oggetto con operator(). std::function può racchiuderlo e chiamare il suo operatore quando viene invocato.

#include <iostream>
#include <functional>

struct Multiplier {
    int factor;
    int operator()(int x) const { return x * factor; }
};

int main() {
    std::function<int(int)> f = Multiplier{3};
    std::cout << f(4) << '\n';
    return 0;
}

Riassegnare la destinazione

Una variabile std::function può riferirsi a diversi oggetti chiamabili durante il proprio ciclo di vita, una soluzione utile per sostituire il comportamento a runtime.

#include <iostream>
#include <functional>

int main() {
    std::function<int(int)> f = [](int x) { return x + 1; };
    std::cout << f(10) << '\n';
    f = [](int x) { return x * x; };
    std::cout << f(10) << '\n';
    return 0;
}

std::function vuoto

Un std::function costruito con il costruttore predefinito non contiene nulla. Chiamarlo genera std::bad_function_call, quindi lo controlli prima.

#include <iostream>
#include <functional>

int main() {
    std::function<void()> f;
    if (f) {
        f();
    } else {
        std::cout << "empty\n";
    }
    return 0;
}

Come parametro

Le funzioni possono accettare un parametro std::function per ricevere qualsiasi oggetto chiamabile compatibile, rendendo le API più flessibili.

#include <iostream>
#include <functional>

void repeat(int n, const std::function<void(int)>& action) {
    for (int i = 0; i < n; ++i) action(i);
}

int main() {
    repeat(3, [](int i) { std::cout << "step " << i << '\n'; });
    return 0;
}

Memorizzare callback

Un uso comune consiste nel conservare una callback in un membro della classe, così da poterla invocare in seguito quando si verifica un evento.

#include <iostream>
#include <functional>

struct Button {
    std::function<void()> onClick;
    void click() { if (onClick) onClick(); }
};

int main() {
    Button b;
    b.onClick = [] { std::cout << "clicked!\n"; };
    b.click();
    return 0;
}

Un vector di oggetti chiamabili

Poiché condividono un unico tipo, diversi oggetti chiamabili possono convivere in un contenitore ed essere invocati in successione.

#include <iostream>
#include <functional>
#include <vector>

int inc(int x) { return x + 1; }

int main() {
    std::vector<std::function<int(int)>> ops;
    ops.push_back(inc);
    ops.push_back([](int x) { return x * 2; });
    for (auto& op : ops) std::cout << op(10) << ' ';
    std::cout << '\n';
    return 0;
}

Il costo del type erasure

std::function può allocare memoria e aggiunge una chiamata indiretta, quindi è leggermente più lento di una chiamata diretta o di un oggetto chiamabile basato su template. Lo usi quando ha bisogno di una memorizzazione uniforme.

#include <iostream>
#include <functional>

int main() {
    std::function<int()> f = [] { return 42; };
    int total = 0;
    for (int i = 0; i < 5; ++i) total += f();
    std::cout << total << '\n';
    return 0;
}

Restituire uno std::function

Una factory può creare e restituire un oggetto chiamabile configurato, consentendo ai chiamanti di ottenere un comportamento personalizzato.

#include <iostream>
#include <functional>

std::function<int(int)> adder(int n) {
    return [n](int x) { return x + n; };
}

int main() {
    auto add5 = adder(5);
    std::cout << add5(10) << '\n';
    return 0;
}

Confronto con i puntatori a funzione

std::function è più flessibile di un puntatore a funzione perché può memorizzare lo stato, ma questa flessibilità comporta un lieve costo in termini di prestazioni e la possibilità di un'allocazione.

#include <iostream>
#include <functional>

int main() {
    int base = 7;
    std::function<int(int)> stateful = [base](int x) { return x + base; };
    std::cout << "Stateful result: " << stateful(3) << '\n';
    return 0;
}

Verifica rapida

Verifichi la Sua comprensione di std::function.

Riepilogo

Ha imparato che std::function:

  • racchiude qualsiasi oggetto chiamabile compatibile con la propria firma, incluse lambda e functor con stato
  • può essere riassegnato, memorizzato in contenitori e restituito dalle factory
  • genera bad_function_call quando è vuoto
  • comporta un lieve overhead dovuto al type erasure

Ora userà std::bind per preimpostare gli argomenti degli oggetti chiamabili.

Domande Frequenti

La lezione «std::function» è gratuita?

Sì — il testo completo di «std::function» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.

Cosa imparerò in «std::function»?

Memorizzare qualsiasi callable Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C++ Academy?

Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «std::function»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C++ Academy?

Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Puntatori a funzione
  2. std::function
  3. std::bind
  4. Scegliere i callable
← Torna a C++ Academy