My question is about this sort of table that's simplified here. Often, I find myself putting this element, (int (*)(const void *, const void *))&strcmp
for bsearch
. I go between prototyping with void pointers, creating dummy functions, and casting, but none is really a satisfactory, especially when the functions are complex.
#include <stdlib.h>
#include <stdio.h>
static void number(int *const);
static void letter(char *const);
static void (*const action[])(void *const) = {
(void (*)(void *))&number,
(void (*)(void *))&letter
};
/* corresponds to the 'action' index */
enum Type { NUMBER = 0, LETTER = 1 };
struct Thing {
enum Type type;
void *data;
};
int main(void) {
const char aah = 'a';
const int five = 5;
const int six = 6;
const struct Thing things[] = {
{ LETTER, (void *)&aah },
{ NUMBER, (void *)&five },
{ NUMBER, (void *)&six }
};
const int things_size = sizeof things / sizeof(struct Thing);
const struct Thing *t;
/* prints a 5 6 */
for(t = things; t < things + things_size; t++) {
action[t->type](t->data);
}
return EXIT_SUCCESS;
}
static void number(int *const dp) {
printf("%d\n", *dp);
}
static void letter(char *const cp) {
printf("%c\n", *cp);
}
This https://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type/559671#559671 seems to suggest that it's dubious to do this. What is the cleanest, most correct way to achieve this sort of polymorphism?