Когда я хочу использовать обобщенный набор кода связанного списка (или, в моем случае, очереди), я встраиваю указатель связанного списка в более крупную структуру, с которой я хочу его использовать. Затем используйте имя поля ссылки при передаче аргументов функциям связанного списка. И есть функция, которая может преобразовывать указатель связанного списка в более крупный указатель структуры, когда я получаю указатели из моего связанного списка. Что-то вроде кода, который вы видите ниже.
Эта идиома не дает вам безопасности типов C ++, но код довольно чистый, с приведением типа локализации к нескольким функциям.
// some representative bits of my linked list API
//
typedef void* PLINK;
extern PLINK LLAddToList(PLINK head, PLINK new);
extern PLINK LLNextItem(PLINK current);
// the structure I want to use it with
typedef struct _foo {
PLINK pLink;
int data1;
int data2;
} FOO;
// to allow for the link pointers to be some other than the first field
// we use this to go from link pointer to structure pointer.
FOO * FooFromPLink(PLINK current) {
return (FOO *)((char *)¤t - FIELD_OFFSET(FOO, pLink));
}
void MyFunction()
{
// this idiom to use the linklist code with a FOO struct
//
FOO * pfoo = // allocate and initialize a foo
LLAddToList(head, &pfoo->pLink);
// this idiom to traverse a list of FOOs, etc.
//
PLINK next = LLNextItem(head);
while (next)
{
pfoo = FooFromPLink(next);
// operate on foo.
next = LLNextItem(next);
}
}