【问题标题】:Allocating a collection of std::shared_ptr's for caching分配 std::shared_ptr 的集合用于缓存
【发布时间】:2017-08-10 04:02:30
【问题描述】:

我有一个元素列表 std::vector<Foo>,我需要将其转换为 std::shared_ptr<Foo> 的列表:

auto make_shared(const std::vector<Foo>& foos)
{
    std::vector<std::shared_ptr<Foo>> result(foos.size());
    std::transform(std::begin(foos), std::cend(foos), std::begin(result), 
                   [] (const Foo& foo) { return std::make_shared<Foo>(foo); });
    return result;
}

我稍后使用std::unordered_map 使用缓存中指向元素的地址。我发现访问地图很昂贵,并且想知道是否可以用std::vector 替换它,因为我知道在第一次缓存查找之前所有元素的地址:

auto complex_calculation(const Foo& foo)
{
    const auto idx = std::distance(first_foo_ptr_, std::addressof(foo));
    // lookup idx in std::vector...
}

据我所知,这样做有两个问题:

  1. 元素在内存中的位置可能不会彼此靠近,这意味着std::vector 的大小可能非常大。这可能吗
  2. operator&lt;(或std::less)不适合根据地址顺序计算偏移量。

在这种情况下是否可以使用自定义分配器来解决这两个问题?

【问题讨论】:

  • 为什么不在向量中通过对象的索引来引用对象?
  • @KerrekSB 因为在将指针的副本分发给其他对象之后,向量会进一步丢失。

标签: c++ c++11 memory-management shared-ptr


【解决方案1】:

正如您所注意到的,std::vector 不会为您节省任何东西(作为固定时间查找),因为向量的大小需要是整个可寻址内存空间(或至少是堆)的大小)。

我将专注于用例:您是要查找包含 Foo 或其他内容的 shared_ptr 实例的地址吗?在前一种情况下,我会研究 shared_from_this,寻找一个可能的简单解决方案。在后一种情况下,您需要考虑其他设计选项(例如:如果您在 shared_ptr 中查找“等效”Foo,请考虑使用 ID 方法和 std::map 查找或等效项)。

【讨论】:

    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2017-07-28
    • 1970-01-01
    • 2012-09-01
    相关资源
    最近更新 更多