Самый простой способ - использовать указатель на функцию.Функции (по одной для каждой версии) получают указатель void * (и, возможно, больше), приводят этот указатель к соответствующей структуре и выполняют свою работу.Интеллектуальное объединение также возможно.
Избегая указателей на функции, вы также можете сделать что-то вроде
switch (ver=get_version()) {
case 1: return do_version_1_stuff(ptr, 1,2,3);
case 2: return do_version_2_stuff(ptr, 1,2,3);
case 3: return do_version_3_stuff(ptr, 1,2,3);
default: fprintf(stderr, "Unknown version %d, call QC!\n", ver);
return -1;
}
ОБНОВЛЕНИЕ: («интеллектуальное объединение» не выглядит четко определенным)
Интеллектуальное объединение - это объединение типов (в большинстве случаев структур), которые служат той же цели, но имеют похожий макет more_or_less.Объединение содержит тип-член, который является общим для всех членов союза и должен использоваться для выбора соответствующего члена.
struct aaaa {
int type;
float value;
};
struct bbbb {
int type;
float value;
char *description;
};
union a_or_b {
struct aaaa a;
struct bbbb b;
};
Если члены не имеют общего поля первого типа,Поле типа может быть помещено вне объединения в структуру-оболочку:
struct kkkk {
float value;
};
struct llll {
float value;
char *description;
};
struct k_or_l {
int type;
union {
struct kkkk k;
struct llll l;
} u;
};
union a_or_b *abp;
struct k_or_l *klp;
Ссылка на материал в объединении теперь будет проходить через abp->a.value
или klp->u.k.value
, например,
int value = abp->a.type==1 ? abp->a.value : abp->b.value;
или, что еще лучше, используя switch (abp->type) {}
.