Я ищу способ удалить избыточность кода.
У меня есть две структуры A
и B
, имеющие переменные-члены x
и y
. Третья структура C
содержит два связанных списка, один с A*
элементами, другой с B*
элементами. Реализация связанного списка не важна, за исключением того факта, что его узлы хранят данные void*
. Поэтому для доступа к элементам этого связанного списка необходимо знать, должны ли данные void*
быть преобразованы в A*
или B*
.
Вот структуры, которые я использую:
typedef struct {
int x;
int y;
double z;
} A;
typedef struct {
int x;
int y;
char t;
} B;
typedef struct {
LinkedList* some_as;
LinkedList* some_bs;
} C;
Теперь проблема в том, что у меня есть две очень похожие функции, определяющие индексы в двух связанных списках в C
, где должны быть вставлены новые элементы A*
и B*
, основываясь на значениях x
и y
. Вот как выглядят эти функции:
int func_for_a(C* c, A* a)
{
int index = -1;
for (Node* node = c->some_as->head; node; node = node->next) {
++index;
A* current = (A*) node->data;
// some checks on a->x, current->x, a->y, and current->y
// these checks affect `index'
}
return index;
}
int func_for_b(C* c, B* b)
{
int index = -1;
for (Node* node = c->some_bs->head; node; node = node->next) {
++index;
B* current = (B*) node->data;
// same checks on b->x, current->x, b->y, and current->y
// these checks affect `index'
}
return index;
}
Я хотел бы сделать абстракцию типа элемента (A*
или B*
), который необходимо вставить в один из двух связанных списков в C
, следующим образом:
int func_for_a_or_b(C* c, TYPE type, void* item)
{
Node* head;
if (TYPE == A) {
item = (A*) item;
head = C->some_as->head;
} else {
item = (B*) item;
head = C->some_bs->head;
}
int index = -1;
for (Node* node = head; node; node = node->next) {
++index;
(TYPE)* current = (TYPE*) node->data;
// checks on current->x, item->x, current->y, and item->y
// these checks affect `index'
}
return index;
}
Это невозможно, потому что я не могу получить доступ к элементам x
и y
из void* item
. Как мне абстрагировать тип элемента? Можно ли использовать макрос? Есть ли другое решение? Заранее спасибо.