使用const char *作为map / unordered_map的关键

时间:2018-05-30 15:25:12

标签: c++ string dictionary

如何创建将const char*直接用作关键字的map / unordered_map?

如果我使用map<std::string,..>,那么在每个解析map["abc"] = ...时,都会创建一个新的std::string对象。这会导致分配内存,创建字符串对象并将字符串复制到其中的大量开销。

如何直接声明使用const char*而没有任何开销的地图对象?

3 个答案:

答案 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)

如果您将指针用作映射键,它将根据指针地址比较键,相同的键将被视为不同。所以在处理普通指针时你必须创建自己的比较函数,所以你最好在普通指针上使用一些包装器,就像其他答案一样。