Puntatori a Funzione e Function-Call Operator
La Programmazione Funzionale è un paradigma che si concentra sul trattare le funzioni come se fossero dei meri “oggetti” passabili qua e là come parametri. È il motore alla base del concetto di Callback (esecuzione asincrona, deleghe).
Le istruzioni delle funzioni vivono fisicamente in un segmento di memoria (il Text Segment). Se hanno un indirizzo in memoria, possiamo costruirci sopra un puntatore.
I Puntatori a Funzione Raw (C-Style)
Section titled “I Puntatori a Funzione Raw (C-Style)”Creare un puntatore a funzione nativo sfoggia purtroppo una delle sintassi più goffe e odiate di tutto il linguaggio C:
tipo_di_ritorno (*nome_del_puntatore)(tipo_arg1, tipo_arg2, ...);
Se vuoi salvare le tue retine oculari dallo scrivere ripetutamente float(*)(float,int) nei parametri delle tue funzioni superiori, usa il magico using per aliasare il tipo:
using OperationFunc = float(*)(float, int);
void fai_matematica(OperationFunc op_scelta) { /* ... */ }L’Operatore Function-Call (operator())
Section titled “L’Operatore Function-Call (operator())”Spesso un semplice puntatore a funzione non basta. Perché? Perché a volte vogliamo che una funzione si porti dietro uno Stato (una memoria interna o variabili configurate dall’utente), cosa che le banali funzioni globali non possiedono.
Siamo in C++, quindi possiamo barare. Possiamo creare una vera e propria Classe, dotarla di tutte le variabili membro che ci pare, e poi sovrascrivere l’Operatore Parentesi operator()(...).
Gli oggetti di questa classe, chiamati Funtori (Function Objects), possono essere “chiamati” con le parentesi simulando di essere funzioni!
La quasi totalità della Standard Template Library (Algoritmi come std::sort, multi-threading std::async) riceve questo tipo di “Funtori” per far elaborare all’utente i propri calcoli complessi custom!