我试图通过将字符串放入 anunordered_set<string>
然后在shared_ptr<string>
's. 很难知道何时删除了对集合中字符串的所有引用,所以我希望 shared_ptr 可以帮助我。这是未经测试的代码,说明了我希望如何编写它:
unordered_set<string> string_pool;
:
shared_ptr<string> a = &(*string_pool.emplace("foo").first); // .first is an iterator
:
shared_ptr<string> b = &(*string_pool.emplace("foo").first);
在上面,字符串“foo”只有一个实例应该在 string_pool 中;a 和 b 都应该指向它;并且在 a 和 b 都被破坏的时候,应该从 string_pool 中删除“foo”。
emplace() 上的文档建议,但没有向我说明,该指针a
可以在由指针分配引起的重新散列中幸存下来b
。它似乎也保证了“foo”的第二个位置不会导致任何重新分配,因为它被认为已经存在于集合中。
我在正确的轨道上吗?我需要防止 string_pool 无休止地增长,但是没有一点可以简单地 clear() 它,也没有任何明确的字符串“所有者”。
更新 1
这个问题的历史:这是一个“交通警察”应用程序,它从服务器读取数据,将数据打包到其他服务器,接收他们的答案,将这些数据打包给其他人,接收,最后组装并返回一个摘要答案。它包括一个应用程序协议栈,用于接收 TCP 消息,将它们解析为字符串标量值,然后应用程序将其组装成其他 TCP 消息,发送、接收等。我最初使用string
s、vectors<string>
s 和字符串引用编写它,并且valgrind报告“大量”字符串构造函数(甚至使用-O3编译),以及集中在与字符串相关的库例程中的高 CPU 使用率。我被要求研究减少字符串复制的方法,并设计了一个“memref”类(char*和指向输入缓冲区的长度)可以复制来代替字符串本身。然后出现了需要重用输入缓冲区的情况,而其中的 memrefs 仍然需要有效,因此我付费将每个缓冲区子字符串复制到一个保留区域 (an unordered_set<string>
),并将 memref 指向那里。然后我发现在这个过程中找到一个可以一次性清除收容区的地方是困难和不方便的(以防止其无限制地增长),我开始尝试重新设计收容区,以便当所有 memrefs 到一个实习字符串不见了,字符串将从池中删除。因此shared_ptr。
正如我在对@Peter R 的评论中提到的那样,我对移动语义、容器和引用甚至比现在更不舒服,而且很可能我没有编写简单的、基于字符串的解决方案来使用所有 C+ +11 可以提供。到现在为止,我似乎一直在绕一个大圈子旅行。