如何创建将const char*
直接用作关键字的map / unordered_map?
如果我使用map<std::string,..>
,那么在每个解析map["abc"] = ...
时,都会创建一个新的std::string
对象。这会导致分配内存,创建字符串对象并将字符串复制到其中的大量开销。
如何直接声明使用const char*
而没有任何开销的地图对象?
答案 0 :(得分:8)
您可以使用std::string_view
:
std::map<std::string_view, int> Map;
Map["abc"] = 1; // no allocation necessary to store "abc"
它基本上是字符串对象的包装器。它是一个视图,这意味着它不拥有字符串,因此不会复制和分配内存来存储字符串。
请注意,对于小字符串(以及文字),由于SSO,std::string
也不会分配,因此开销很小。始终在优化之前进行测量。
答案 1 :(得分:5)
作为Rakete1111's string_view
answer的替代方案,您可以为地图配备合适的比较器(以及unordered_map
的哈希):
struct LesserString
{
bool operator() (const char *lhs, const char *rhs) const
{
return std::strcmp(lhs, rhs) < 0;
}
};
struct HashString
{
std::size_t operator() (const char *arg) const
{
return however_you_want_to_hash_the_string();
}
};
struct EqualString
{
bool operator() (const char *lhs, const char *rhs) const
{
return !strcmp(lhs, rhs);
}
};
std::map<const char*, WhateverValue, LesserString> m1;
std::unorderd_map<const char*, WhateverValue, HashString, EqualString> m2;
答案 2 :(得分:0)
如果您将指针用作映射键,它将根据指针地址比较键,相同的键将被视为不同。所以在处理普通指针时你必须创建自己的比较函数,所以你最好在普通指针上使用一些包装器,就像其他答案一样。