7

The boost::intrusive documentation describes how you can use smart pointers with intrusive containers but then says you can't use the smart pointers you'd be most likely to use, "It must have the same ownership semantics as a raw pointer. This means that resource management smart pointers (like boost::shared_ptr) can't be used."

Why is this? I can't think of any obvious reason they should be prohibited. What exactly would break? Intrusive containers don't manage allocation of the items inside them anyway. In my case I'd like to use intrusive_ptr, but I don't see any reason why shared_ptr shouldn't work either.

Edit: To be clear, I mean for the hook pointer (e.g. the next pointer in an intrusive singly linked list) to be a smart pointer.

Joseph Garvin
  • 20,727
  • 18
  • 94
  • 165

3 Answers3

2

Perhaps there's a clue in the documentation for boost::intrusive::slist where it states that with the default configuration, slist is stored as a circular list, which precludes using shared_ptr/intrusive_ptr and friends, because you'd have a reference cycle.

It's still annoying that one part of boost doesn't work properly with another; I guess the only the workaround would be to use something like intrusive_ptr and manually bump the reference count when you add an object to the container, and decrement it when you remove it. (This rules out shared_ptr, because you can't adjust its reference count directly.)

Nick Hutchinson
  • 5,044
  • 5
  • 33
  • 34
0

One obvious reason is efficiency. shared_ptr uses atomic increment/decrement operations to count references. This means that disposing large enough container that uses shared_ptr pointers under the hood will take seconds, because every reference counter need to be decremented atomically.

Evgeny Lazin
  • 9,193
  • 6
  • 47
  • 83
  • 3
    I mention intrusive_ptr which does not have that problem. Also this doesn't really answer the question, which is why the documentation says you can't do it. That's different from whether it may be a good idea. – Joseph Garvin Dec 14 '12 at 06:53
0

Presumably this is because intrusive containers already manage the memory internally (like theboost ptr_ containers), and instead of creating two distinct instrusive container implementations (one for non-owning pointers and one for owning) they decided to put the restriction on what type(s) of point can be used.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • As I said in my question, they don't manage the memory internally. You have to allocate and free items that go into an intrusive container yourself. Adding/removing items from the container performs no allocations/frees and no copies. – Joseph Garvin Dec 14 '12 at 15:42