我正在编写一个具有高性能线程的应用程序,该线程不允许分配。我有一张如下所示的地图:
map<String, MyCustomClass> objectCollection;
其中String是围绕std :: string的自定义包装器。我希望能够在高优先级的线程上编写这样的代码:
int someValue = objectCollection["some string"].value;
当我这样做时,索引到数组会导致构造一个String,这需要分配。我的想法是,我可以为我的地图定义一个自定义比较器,它接受一个const char *,并且能够与String的c字符串guts进行字符串比较。这可能吗?怎么样?
我可以使用String实例执行类似的操作:
String strTest = "";
const char* chars = strTest.chars();
答案 0 :(得分:3)
你可以只做一次分配。
static const string Key("some string");
int someValue = objectCollection[Key];
使用零分配执行此操作将需要不同的字符串类。你会以某种方式利用const char*
和自定义比较机制。
答案 1 :(得分:3)
自定义比较对你的地图没有任何好处;无论比较运算符如何工作,查找运算符始终将其参数转换为键类型。但是当你想要快速查找时,可能有更好的方法。
将事物保存在已排序的向量中并使用二进制搜索算法(lower_bound()等)查找它们通常比在地图中查找它们更快(因为,除其他外,地图的内部树结构在每次查找时强加了大量的指针追逐)。插入的映射比排序的矢量快得多,但是当快速查找比快速插入更重要时,向量通常更快,并且向量的优点是可以使用异构比较函数(需要两个不同的参数)类型)。
这样的事情:
struct Element {
std::string key;
Thing value;
};
bool compare(const Element& lhs, const char* rhs) {
return lhs.key < rhs;
}
using Collection = std::vector<Element>;
inline Thing lookup(const char* key, const Collection& coll) {
// Requires coll to be already sorted
auto i(std::lower_bound(coll.begin(), coll.end(), key, compare));
if (i != coll.end() && i->key == key)
return i->value;
else
return Thing();
}
答案 2 :(得分:2)
在C ++ 14中,有一些巧妙的新功能应该允许这种情况发生。例如,有一个模板化的map :: find
template< class K > iterator find( const K& x );
答案 3 :(得分:1)
你所能做的就是将key_type更改为const char *,因为map :: find以及map :: operator []以及map :: at take key_type作为参数。因此,即使你传递一个const char *,它也会在map函数被调用之前构造一个String。因此,除非你使你的String静止,否则你不会在没有构建它的情况下逃脱。