Home > other >  Why is shared_ptr implemented using control block and not a static map?
Why is shared_ptr implemented using control block and not a static map?

Time:01-11

To me, it looks like an implementation of std::shared_ptr which stores a reference counter in a static std::unordered_map<void*, struct Counters> would be much more simpler and also allow us to avoid some dirty workarounds like std::enable_shared_from_this (because std::shared_ptr<T>{this} wouldn't create new control block, only increment a counter for a pointer that already exists in a map).

So why does a committee decided to stick with a control block implementation?

CodePudding user response:

So why does a committee decided to stick with a control block implementation?

It doesn't. The committee writes requirements that implementers must follow. They do not specify that std::shared_ptr be implemented in any particular way, so long as that way meets the requirements.

Having said that, your proposed static std::map<T*, size_t> runs foul of this general (unless otherwise specified) requirement:

A C standard library function shall not directly or indirectly access objects ([intro.multithread]) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including this.

[res.on.data.races#2]

Another compelling reason is that std::shared_ptr type-erases the deleter, so at best you'd have a static std::map<void *, struct { size_t count; size_t weak_count; std::function<void(void*)> deleter; }>, at which point you have two dynamic allocations for the control block, rather than the one (possibly merged with the owned object) that current implementers prefer.

  •  Tags:  
  • Related