【发布时间】:2015-05-08 21:14:19
【问题描述】:
我正在为大量对象创建多个索引(即使用不同键的索引)。对象可以改变,集合可以缩小和增长。到目前为止我的想法:
保留多个指向对象的指针的集合。 使用 set 代替 map 以获得更好的封装。 使用 unordered_set 可以很好地处理大型数据集。 理想情况下,指针应该都是某种形式的智能指针。
我可以从一个管理所有分配的唯一_ptrs 主集合和使用“原始”指针的二级索引开始相当容易(我将暂时省略支持函数,但请注意索引是multiset 作为它的键在集合中不会是唯一的):
typedef boost::unordered_set< boost::unique_ptr<MyObject>,myobject_hash,myobjects_equal > MyObjects;
typedef boost::unordered_multiset<const MyObject*,myobject_index2_hash,myobject_index2_equal > MyObjectsIndex2;
用法很简单:
MyObjects my_objects;
MyObjectsIndex2 my_objects_index2;
auto it_mo = my_objects.insert(
boost::unique_ptr<MyObject>(
new MyObject(...)
)
);
const MyObject* p_mo = it_mo.first->get();
my_objects_index2.insert(p_mo);
我正在考虑付出额外的努力,将索引对原始指针的使用替换为对主集合的 unique_ptrs 的 const 引用。我不确定我能不能,至少不容易。我想我会问其他人是否已经走这条路,或者有其他建议。
更新
到目前为止的经验教训:
- 数据存储类很酷
- reference_wrappers 很酷
- 带有“key”对象数据存储成员 var 的 xx_set 比 xx_map 更节省空间。但是...您不能轻易地将 unique_ptr 用作 c++11 中的键。 c++14 显然可能通过
std::set<Key>::find具有更好的设置功能。有关详细信息,请参阅here。因此,就目前而言,管理原始分配的数据存储似乎比尝试强制使用 unique_ptr 作为设置键或使用映射增加键空间存储更有意义。 - 记住在对象的生命周期内强制键值为 const(使用构造函数中提供的 const 值)
【问题讨论】:
-
对唯一指针的引用将不起作用,因为这些指针会随着主存储结构的增长而重新分配(除非它以某种方式被写入以保持对象到位)。除非您愿意存储对象的多个副本,否则您无法真正绕过这里需要第二层间接,这会浪费大量空间。无论如何,我认为在主存储中使用共享指针会更好,在索引中使用弱指针。
-
谢谢 Wug,关于移动 unique_ptrs 的要点,这将是另一个需要管理的细节。是的,共享+弱指针方法会起作用,但会以引用计数为代价。这还不错。我对此有点着迷,因为它是如此基础。我认为原始指针方法似乎还可以……我仍在考虑它……
-
让我看看能不能做点有用的事。