Using const char* as key for map/unordered_map

2020-07-18 04:21发布

How to create map/unordered_map that will use const char* as key directly?

If I use map<std::string,..>, then on each resolving map["abc"] = ... a new std::string object will be created. That causes a big overhead for allocating memory, creating a string object and copying the string into it.

How do I declare a map object that uses const char* directly without any overhead?

3条回答
兄弟一词,经得起流年.
2楼-- · 2020-07-18 04:46

As an alternative to Rakete1111's string_view answer, you can equip your map with a suitable comparator (and hasher, for the 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;
查看更多
地球回转人心会变
3楼-- · 2020-07-18 04:47

If you will use pointer as map keys it will compare keys based on pointer addresses, the same keys will be treated as different. So you will have to create your own comparison function when dealing with plain pointers, so you will better use some wrapper on plain pointers like other answer suggested.

查看更多
SAY GOODBYE
4楼-- · 2020-07-18 04:50

You can use a std::string_view:

std::map<std::string_view, int> Map;
Map["abc"] = 1; // no allocation necessary to store "abc"

It is basically a wrapper around string objects. And it's a view, which means that it doesn't own the string and thus doesn't copy and allocate memory to store a string.

Note that for small strings (and also literals), std::string doesn't allocate too due to SSO and so the overhead is minimal. Always measure before optimizing.

查看更多
登录 后发表回答