The naivety of an 'intrusive' list, where all your objects are always 'list ready', is that it allows the insertion and removal of elements without copying them, which is beneficial if your lists experience a lot of churn. The thing is, you can achieve this without intrusion anyway by keeping all your 'not in a list' items... well, in a list. You then get memory management for free and can use splice()[0] to efficiently move nodes around.
My philosophy on lists is: if you've never used or needed to splice then you probably don't really need a linked list. Splicing is what linked lists are all about.
With intrusive list you need only modify any element on a single place (A bullet location as an example).
How could you achieve this with std::list?
It was explained in the original article "If you want your structure to be in two lists at the same time, you have to add another field: " with an example.
I just wanted to spell out that in most use cases intrusion is a sucky trade-off with no benefit.
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 have no idea how to implement something that has same memory locality and capabilities as intrusive list with std::list and that's why I'm asking how it's done. Storing a pointer does not have same memory locality.