std::shared_ptr<std::string const> 可以作为引用计数不可变字符串的有效实现吗?

sh-*_*sh- 5 c++ string std immutability

理想情况下,不可变字符串类只需要为每个字符串分配一次内存。甚至引用计数也可以存储在保存字符串本身的同一块内存中。

string和的简单实现shared_ptr将为 分配三个不同的内存shared_ptr<string const>

  • 字符串缓冲区的内存
  • 字符串对象的内存
  • 引用计数的内存

现在,我知道在使用 时std::make_shared(),智能实现可以将后两者合并为一个分配。但这仍然会留下两个分配。

当您知道字符串是不可变的时,字符串缓冲区将不会被重新分配,因此应该可以将其与字符串对象集成,只留下一次分配。

我知道某些字符串实现已经对短字符串使用了此类优化,但我正在寻找一个无论字符串长度如何都可以执行此操作的实现。

我的问题是:我的推理合理吗?实施实际上是否允许并且能够做到这一点?我可以合理地期望一个高质量的标准库来实现这种优化吗?您知道当代图书馆的实现可以做到这一点吗?

或者这是我必须自己实现的事情?

Dan*_*Dan 1

我相信做到这一点的唯一方法是make_shared接受运行时可变大小的数组。标准版本没有,即使从 c++17 开始也是如此(它增加了对shared_ptr数组的支持)。

另一方面,Boost 有boost::make_shared,它也可以接受数组大小参数。一旦你拥有了它,你就是黄金;你会得到一个shared_ptr<char[]>几乎可以满足你想要的功能(除了实际上是一个std::string.

如果你不想使用 boost,你可以自己推出。可能不会那么难。

其他需要考虑的事情是,如果您只创建 O(1) 字符串,那么从不删除它们并传递原始指针(或std::string_views)会更快。这可以避免任何复制或修改引用计数。(引用计数实际上非常慢,因为它们使用原子操作。)

您还可以使用诸如 之类的实习机制std::unordered_set<std::string>