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

nik*_*nik 3 c++ string dictionary

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

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

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

Rak*_*111 8

你可以使用std::string_view:

std::map<std::string_view, int> Map;
Map["abc"] = 1; // no allocation necessary to store "abc"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这是辉煌的,隐隐的可怕。想想我们将在看似理智的程序中获得的滥用和随后的 UB :/ (2认同)

Rei*_*ica 5

作为Rakete1111 string_view答案的替代方案,您可以为地图配备合适的比较器(以及用于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;
Run Code Online (Sandbox Code Playgroud)