I'll give you a pointer to an element and you remove it from all containers that it is currently on, in O(1).
The only way to do that is to keep a bunch of iterators in the item itself, which is virtually identical to the intrusive container model except it involves more pointers, more heap allocations and introduces an extra invariant into the data model (the iterator stored in the item must point at a list that actually contains said item). And the only benefit you get for all this pain and suffering is that you don't have to do any "funny" casting via container_of() contraptions.
Point being is that once data items sit in more than one container, intrusive container model generally results in a simpler code that is also more efficient.
I'll give you a pointer to an element and you remove it from all containers that it is currently on, in O(1).
The only way to do that is to keep a bunch of iterators in the item itself, which is virtually identical to the intrusive container model except it involves more pointers, more heap allocations and introduces an extra invariant into the data model (the iterator stored in the item must point at a list that actually contains said item). And the only benefit you get for all this pain and suffering is that you don't have to do any "funny" casting via container_of() contraptions.
Point being is that once data items sit in more than one container, intrusive container model generally results in a simpler code that is also more efficient.