当键是对象的一部分时,最合适的关联STL容器
Most appropriate associative STL container when key is part of object [C++]
我有一个这样的类:
struct Thing
{
unsigned index;
// more data members
};
我使用一个std::map<Thing>
来包含我的Thing
s。调用代码看起来像这样:
Thing myThing(/*...*/);
std::map<Thing> things;
things[myThing.index] = myThing;
// ...
Thing &thing3 = things[3];
我想知道是否有一种方法可以直接使用Thing::index
,而不需要隐式地将其复制到pair::first
。
我想我需要提供某种Thing
比较运算符,但这没关系。std::set
可能工作,但我需要一个完整的Thing
对象作为键:
std::set<Thing> things;
Thing &thing3 = *things.find(Thing(3));
除了将Thing
重构为std::pair
,我可以用STL做得更好吗?
我不明白为什么
inline bool operator<(const Thing& a,const Thing& b) {
return (a.index<b.index);
}
std::set<Thing> things; // Uses comparison operator above
Thing &thing3 = *things.find(Thing(3));
并不完全符合您的要求。没有重复/复制索引字段,键比较与映射方法一样高效;有什么不喜欢的呢?
根据下面的注释更新
如果Thing太重量级了,你不想复制它,那么你可能会得到这样的代码:
inline bool operator<(const shared_ptr<Thing>& a,const shared_ptr<Thing>& b) {
return (a->index < b->index);
}
std::set<shared_ptr<Thing>> things; // Uses comparison operator above
shared_ptr<Thing> key3(new Thing(3));
Thing &thing3 = *things.find(key3);
虽然在我看来,重写指针值比较是相当邪恶的,最好是走更详细的路线,显式的"Compare"参数设置模板参数。
有一件事要记住(根据我自己对重量级对象的大优先级队列的经验):与std::pair<trivial_key,heavyweight_object>
相比,基于std::pair<trivial_key,shared_ptr<heavyweight_object>>
的容器可能有显著的优势,因为前者的遍历只触及键(例如find
),与后者相比,可以更高效的缓存,这也会将大量不需要的/不相关的heavyweight_object
字节获取到缓存中(当然取决于细节和数字,但实际上这种效果可以很容易地完全淹没复制键的相对较小的成本)。用私有继承或组合包装映射,重新导出访问器并根据所需的功能实现插入。我建议在key getter上对新类型进行参数化——key getter是一个函数,在给定存储类型的对象时返回一个键。
回想一下,boost::flyweight支持键提取器,以避免在可以从对象中轻松获得键时为键保留额外的存储空间。
我不建议在map
或unordered_map
足够的所有情况下使用flyweight,我很难相信这些类不支持类似的键提取模式,尽管我在文档或谷歌中找不到任何提及。无论哪种情况,这都可能对您有所帮助
如何使用您的对象的内存地址作为一个键在您的地图?
std::map< void*, std::shared_ptr<MyObject> > myMap;
myMap.insert( std::pair<void*, std::shared_ptr<MyObject> >(object.get(), object) );
所以你不需要在对象中存储键我认为这是一个坏主意因为键与对象状态没有任何关系
相关文章:
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 内存错误低于在C++年实现埃拉托色尼筛分时的预期
- 在C++中迭代 STL 集时出现奇怪的问题<CStudent>
- glibcxx STL 在实现 std::valarray::sum() 时是否不正确?
- 为什么将指针重新分配给 1D 数组的 char 时显示错误,但 2D 数组工作正常?
- 如何在 android ndk 上链接 C 和 C++ 代码,以及 C 和 C++ 运行时库(包括 STL)?
- 分配给gslice_array会导致运行时错误
- 将双精度值分配给 int 数组时的类型转换
- 现代C++中STL API的差异(当我在VS2017中将目标从x64切换到x86时)
- 为什么双精度引用值在分配给C++中的浮点变量时不会更改
- C++ 使用数组初始化时的 STL 向量内存管理
- 为什么SADWinowSize_slider的跟踪栏的值在分配给 sbm->state 时变为 0。SADWindowSize,在我的代码中
- 错误:将"long int (*)[4]"分配给"long int [4][4]"时的类型不兼容
- 当我输入分数值时,它返回不正确的结果
- 将 lambda 传递给 STL 集时出错"bad function call"
- 当我使用unordered_map时,如何使c ++_static stl在Android Studio中正常工作
- 使用队列和列表 STL 进行C++分配。在将数据填充到列表或队列中然后打印该数据时遇到问题
- C 在将数组引用分配给struct时麻烦
- 当我的电脑得分达到100分时,游戏还没有结束