Sto scrivendo una funzione che riceve un puntatore a una funzione di confronto e una serie di MyStructs
e si suppone per ordinare l'array in base alla funzione di confronto:Casting puntatori a funzione
void myStructSort(
struct MyStruct *arr,
int size,
int (*comp)(const struct MyStruct *, const struct MyStruct *)) {
qsort(arr, size, sizeof(struct MyStruct), comp);
}
Purtroppo questo non viene compilato poiché qsort
prevede che il comparatore riceverà gli argomenti void *
e non const struct MyStruct *
. Ho pensato a diverse soluzioni sbagliate e mi chiedevo quale fosse la soluzione corretta.
Opzione 1
Fusioni comp
-int (*)(const void *, const void*)
. Compilare ma è un comportamento non definito (vedere this SO question).
Opzione 2
Creare una variabile globale int (*global_comp)(const struct MyStruct *, const struct MyStruct *)
e impostare global_comp=comp
all'interno myStructSort
. Quindi creare una funzione:
int delegatingComp(const void *a, const void *b) {
return globalComp((const struct MyStruct *)a, (const struct MyStruct *)b);
}
E in myStructSort
chiamata qsort(arr, size, sizeof(struct MyStruct), delegatingComp)
. Il problema con questa è la variabile globale icky.
Opzione 3
reimplementare qsort
. Questa è una pratica funzionalmente sicura ma molto cattiva.
Esiste una magica quarta opzione perfetta?
Modifica
Non posso cambiare le API di myStructSort
e sto compilando il mio codice utilizzando gcc c99 -Wall -Wextra -Wvla
.
In tal caso, una funzione di wrapper come quella che hai trovato nell'opzione 2 è l'approccio migliore. A proposito, non ho proprio avuto l'idea delle variabili globali che hai menzionato. A cosa servono? – HighPredator
HighPredator @, 'delegatingComp' deve sapere quale funzione chiamare e non può essere passata ad essa come argomento perché deve corrispondere all'argomento di' qsort'. –
se si utilizza 'gcc', l'estensione di gnu consente di definire una sottofunzione all'interno di una funzione. simula una chiusura basata sullo stack. se non ti dispiace il danno alla portabilità, puoi provarlo. – HuStmpHrrr