std::function
è un oggetto di cancellazione del tipo. Ciò significa che cancella i dettagli di come si verificano alcune operazioni e fornisce loro un'interfaccia di runtime uniforme. Per std::function
, il primario1 Le operazioni sono copia/mossa, distruzione e "invocazione" con operator()
- La "funzione come operatore di chiamata".
In inglese meno astruso, significa che std::function
Può contenere quasi tutti gli oggetti che si comportano come un puntatore di funzione nel modo in cui lo si chiama.
La firma che supporta va all'interno delle parentesi angolari: std::function<void()>
Non prende argomenti e non restituisce nulla. std::function< double( int, int ) >
ne prende due int
argomenti e ritorni double
. In generale, std::function
Supporta la memorizzazione di qualsiasi oggetto simile a una funzione i cui argomenti possono essere convertiti dal suo elenco di argomenti e il cui valore di ritorno può essere convertito nel suo valore di restituzione.
È importante saperlo std::function
E lembdas sono diverse, seppure compatibili, bestie.
La prossima parte della linea è una lambda. Questa è una nuova sintassi in C ++ 11 per aggiungere la possibilità di scrivere semplici oggetti simili a funzioni: oggetti che possono essere invocati ()
. Tali oggetti possono essere digitati e conservati in a std::function
Al costo di un po 'di tempo di esecuzione.
[](){ code }
In particolare è una lambda davvero semplice. Corrisponde a questo:
struct some_anonymous_type {
some_anonymous_type() {}
void operator()const{
code
}
};
Un'istanza del semplice tipo di pseudo-funzione semplice. Una classe effettiva come quella sopra è "inventata" dal compilatore, con un nome univoco definito implementazione (spesso inclusi simboli che non può contenere un tipo definito dall'utente) (non so se è possibile che tu possa seguire lo standard senza inventare Tale classe, ma ogni compilatore che conosco crea effettivamente la classe).
La sintassi completa di lambda sembra:
[ capture_list ]( argument_list )
-> return_type optional_mutable
{
code
}
Ma molte parti possono essere omesse o lasciate vuote. Capture_list corrisponde sia al costruttore del tipo anonimo risultante che alle sue variabili membri, l'argomento_list gli argomenti del operator()
, e il tipo di ritorno il tipo di ritorno. Il costruttore dell'istanza Lambda è anche magicamente chiamato quando l'istanza viene creata con cattura_list.
[ capture_list ]( argument_list ) -> return_type { code }
fondamentalmente diventa
struct some_anonymous_type {
// capture_list turned into member variables
some_anonymous_type( /* capture_list turned into arguments */ ):
/* member variables initialized */
{}
return_type operator()( argument_list ) const {
code
}
};
Nota che in C ++ 20 Gli argomenti dei modelli sono stati aggiunti a Lambdas e questo non è coperto sopra.
[]<typename T>( std::vector<T> const& v ) { return v.size(); }
1 Inoltre, RTTI è memorizzato (typeid) e è inclusa l'operazione di tipo cast-a-originale.