I often that the intrusive approach that rachetfreak mentioned is the simplest. It can consume extra memory if the user has a list of Foos, a red-black tree of Foos, etc, since Foo now has to have a struct list_head, struct rb_node, etc. in it, but that's really not that bad of a trade-off for the simplicity. If it comes down to it, users can work around those sorts of problems with clever memory tricks. Linus Torvalds agrees, as Linux is the most popular example of this approach. You can find the implementation
here, and there are many explanations of it on the internet. A good one is found in
Linux Kernel Development, if you're into books.
To give more detailed information, we would need to see your exact use case.