Nei vecchi linguaggi non orientati ad oggetti potevamo farlo, poiché un comando apposito (solitamente "do") chiamava una routine che, preceduta da "&", eseguiva il valore contenuto nella locazione di memoria. La stessa cosa non riesco a farla con la chiamata delle funzioni.
Ho anche pensato che, in alternativa, si potesse chiamare una funzione (senza passare argomenti) chiamando il puntatore dove la funzione specifica viene allocata in memoria. Ma non so se si può fare. In altri casi simili ho anche scritto 2 array paralleli, in uno dei quali sono contenuti i testi di variabili di memoria, nell'altro l'indirizzo del puntatore, ma non riesco ad applicare la tessa tecnica nel mio caso.
In pratica, vorrei chiamare una funzione diversa a seconda del contesto, più precisamente a seconda del valore che assume una variabile di memoria, che potrebbe contenere il nome della funzione da chiamare.
una cosa del tutto simile avviene con la chiamata di "attachInterrupt", quando viene passato come argomento il nome della funzione da chiamare in caso di interrupt.
Per adesso conosco solo la via lunga, che prevede il ricorso a "switch/case".
Qualcuno conosce la scorciatoia ?
Chiamata di una funzione il cui nome è contenuto in una variabile String
Non è possibile direttamente in C++.
Una volta che il codice è compilato, i nomi delle funzioni scompaiono.
Altrimenti c'è il metodo "pesante"
void chiamataFunzione(String& nomeFunzione) {
if (nomeFunzione == "funzione1") funzione1();
else if (nomeFunzione == "funzione2") funzione2();
else if (nomeFunzione == "funzione3") funzione3();
else if (nomeFunzione == "funzione4") funzione4()
...
};
?? non mi pare c'entri nulla il discorso del orientato agli oggetti.
Richiamare funzioni in base al nome contenuto in stringa lo ricordo solo in linguaggi interpretati (basic,python) e non in quelli compilati (tipo C e C++).
Hai linguaggi che possono essere compilati ma che mantengono un runtime/VM (Objective-C, Java, ...) con informazioni e quindi possono offrire la chiamata di una funzione per il suo nome dal codice sorgente.
Periodicamente domande del genere tornano
Ma si tratta sempre di problemi di analisi propedeutica del problema
In fin dei conti se devo ricevere una variabile quella variabile deve esistere ed essere stata allocata correttamente
A quel punto gestirne correttamente la ricezione diventa semplicemente un problema di organizzazione
Come ti hanno già risposto non c'è modo di farlo come eri abituato a fare, ma non c'è nulla che non si può risolvere con un po' di C++
Potresti fare una cosa del genere ad esempio:
// Dichiarazione del tipo di dati per la funzione void(void)
typedef void (*FunctionPtr)(void);
// Struttura che memorizza il puntatore alla funzione e il nome
struct MyFunctions {
const char* name;
FunctionPtr function;
};
// Array di struct MyFunctions
MyFunctions functions[] = {
{"funzione1", funzione1},
{"funzione2", funzione2},
{"funzione3", funzione3},
{"funzione4", funzione4}
};
...............
...............
for (auto & item : functions) {
if (inputStr.indexOf(item.name) > -1) {
// Se la variabile contiene il nome della funzione da chiamare
item.function();
}
}
Esempio wokwi funzionante:
Ciò sarà un problema se hai nomi come funzione1
e funzione12
.
Si certo, ma è solo un possibile esempio.
Se dovesse esserci l'eventualità di due "nomi funzioni" molto simili, andrà gestita opportunamente.
➜
if (inputStr == item.name) { // inputStr è un'istanza di String
...
}
Il condizionale usato dall'OP mi ha fatto supporre che la variabile potrebbe contenere altro oltre al nome della funzione, ragione per cui nell'esempio ho usato indexOf()
➜ OK ! Bene
Grazie per il suggerimento. In realtà, la differenza tra funzione e comando è proprio il passaggio di parametri in ingresso e in uscita. Grazie alla tua risposta ho provato con successo a creare un puntatore a funzione che, però, si può utilizzare SOLO per funzioni che hanno gli stessi parametri in ingresso ed in uscita, uguali anche per TIPO di variabili. Ciò significa che se devo puntare a funzione funzioni con diversa struttura (o forse è meglio chiamarla matrice), devo creare tante typedef per quante sono le matrici delle funzioni puntate. Ad esempio:
se creo una typedef come nella tua risposta posso puntare solo funzioni che non hanno nessun parametro. Se invece ne hanno, devo creare typedef apposite.
Altra cosa utile nella tua risposta è che non posso puntare a funzione il contenuto di una variabile string, ma solo il nome espresso come fosse una costante.
Vedo che ogni tanto tornano su web domande di questo tipo, quasi sempre abbandonate cone non risolvibili. Questa mi sembra una bella soluzione
Lavorando un po' con la struct potresti "aggirare" anche questo limite prevedendo due o più puntatori a funzioni diverse ed una variabile che identifica il tipo, magari usando un enum.
Poi nel ciclo for usando uno switch/case chami la funzione giusta.
A dirla tutta però non è una soluzione che mi fa impazzire...
Forse sarebbe più elegante definire la tua funzione in modo più elastico possibile prevedendo tutti i parametri per ogni casistica con dei valori predefiniti che cambi solo quando necessario.
Nell'esecuzione della funzione, quando il parametro è diverso da quello predefinito (di solito si usa -1) esegui il blocco di codice di pertinenza.
Ancora meglio potrebbe essere usare una funzione di tipo "variadic" (come ad esempio lo è printf) dove il numero dei parametri può essere variabile (ma noto a compile time)
Finzioni variadiche non hanno numero e tipo degli argomenti noto a compile-time
Altrimenti non sarebbero di alcuna utilità, basterebbe l'overload, al massimo assieme agli argomenti di default
Prova a passare alla printf() del C una stringa di formato scritta a runtime e vedrai che la interpreta correttamente
Ci sembra che sul K&R ci sia scritto che "magia" hanno usato
Il contraltare è che si tratta di una tecnica insicura e prona ad attacchi maliziosi
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.