我真的不明白我是否理解你的观点,但我认为你可以做的是实现一些短的 polymorphic struct
s。在您的情况下node
是标签和dllnode
类型。标签是引用结构本身内的结构所必需的,这就是为什么您的最后一条语句失败并且唯一struct node
合法的原因。在静态设计中不能有动态行为。所以如果我是你,我会把设计改成这样:
struct dllnode{
node super;
dllnode *next;
dllnode *prev;
size_t elem_size;
void *payload;
uint32_t flag;
};
struct node{
node *next;
node *prev;
size_t elem_size;
void *payload;
};
所以你可以在你的代码中有一个原始类型node
和多个“子”类型,dllnode
或者你需要的任何其他节点类型!通过将父亲(节点)转换为孩子(dllnode),您可以在两个结构之间交换值。这是因为 C 标准规定结构的第一个成员与结构的开头对齐。例如:
void add_dllnode(struct node *s)
{
struct dllnode *self = (struct dllnode *) s;
self->next = s->next;
self->prev = s->prev;
self->elem_size = s->elem_size;
self->payload = s->payload;
// you can now do treat node as if it's dllnode and probably add it to
// one of your lists
}
In addition whenever you create a node
you can tune the flag member to something like NODE_TYPE_DLL
or NODE_TYPE_OTHER
and use it as a condition for your invocations, e.g.:
struct node s;
init_node(s);
...
if(((s->flag) & NODE_TYPE_DLL))
add_dllnode(s);
else
...
...