为什么 shared_ptr 使用控制块而不是静态地图实现?

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

对我来说,在 static std::unordered_map<void*, struct Counters> 中存储引用计数器的 std::shared_ptr 的实现看起来会简单得多,并且还允许我们避免一些肮脏的解决方法,例如 std::enable_shared_from_this(因为std::shared_ptr<T>{this}不会创建新的控制块,只会为映射中已存在的指针增加计数器)。

那么为什么委员会决定坚持控制块实施?

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

没有。委员会编写实施者必须遵守的要求。他们没有指定 std::shared_ptr 以任何特定方式实施,只要该方式满足要求即可。

话虽如此,您提议的 static std::map<T*, size_t> 违反了此一般要求(除非另有说明):

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]

另一个令人信服的原因是 std::shared_ptr 类型擦除删除器,因此您最多只有一个 static std::map<void *, struct { size_t count; size_t weak_count; std::function<void(void*)> deleter; }>,此时您有 两个 控制块的动态分配,而不是当前实现者喜欢的 one(可能与拥有的对象合并)。