【问题标题】:Using const char* as key for map/unordered_map使用 const char* 作为 map/unordered_map 的键
【发布时间】:2018-11-09 12:40:07
【问题描述】:

如何创建直接使用const char* 作为键的map/unordered_map?

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

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

【问题讨论】:

  • 在抱怨“开销”之前,测试它对其进行基准测试,并对其进行分析。不,您不能真正使用任何类型的指针作为键,因为那样它将是 pointer 是键而不是它指向的内容。
  • 这不会起作用,因为 std::hashstd::equal_to 的默认特化将无法像您预期的那样运行。
  • 密钥字符串有多长?你期望有多少不同的?键是可变的还是固定的?密钥的寿命是多久?
  • 使用字符串键查找元素需要 70 纳秒,但使用长长键需要 20 纳秒。使用 const char* 我期望结果接近 long long。 std::string 内存分配的任何方式都可能发生,这是不可接受的。

标签: c++ string dictionary


【解决方案1】:

您可以使用std::string_view

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

它基本上是一个字符串对象的包装器。它是一个视图,这意味着它不拥有字符串,因此不会复制和分配内存来存储字符串。

请注意,对于小字符串(以及文字),std::string 由于SSO 而不会分配太多,因此开销很小。始终在优化之前进行测量。

【讨论】:

  • 如果你没有 C++17,你可以使用absl::string_view(实际上你可以在这两种情况下使用它,因为如果它存在)。
  • @jdehesa 或 boost::string_view :)
  • std::string_view 可能是一个不错的功能,但不幸的是它将采用新标准,现在我的编译器 vc++12 中不存在((
  • 升级到 vc15 或 vc17。你会很高兴你做到了。说真的。
  • 这太棒了,也有点可怕。想想我们将在看起来正常的程序中得到的滥用和随后的 UB:/
【解决方案2】:

作为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;

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-29
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多