C字符串映射键

use*_*967 4 c++ map cstring

使用C字符串作为地图密钥有什么问题吗?

std::map<const char*, int> imap;
Run Code Online (Sandbox Code Playgroud)

地图中元素的顺序无关紧要,所以如果按顺序使用它们也没关系std::less<const char*>.

我正在使用Visual Studio并根据MSDN(Microsoft特定):

在某些情况下,可以"合并"相同的字符串文字以节省可执行文件中的空间.在字符串文字池中,编译器会将对特定字符串文字的所有引用指向内存中的相同位置,而不是让每个引用指向字符串文字的单独实例.

它说它们仅在某些情况下被合并,所以看起来使用字符串文字访问地图元素似乎是一个坏主意:

//Could these be referring to different map elements?
int i = imap["hello"];
int j = imap["hello"];
Run Code Online (Sandbox Code Playgroud)

是否可以重载operator==const char*使实际的C字符串而不是指针值用于确定映射元素是否相等:

bool operator==(const char* a, const char* b)
{
    return strcmp(a, b) == 0 ? true : false;
}
Run Code Online (Sandbox Code Playgroud)

使用C字符串作为映射键是否是一个好主意?

Luc*_*ore 6

是否可以为 const char* 重载 operator==,以便使用实际的 C 字符串而不是指针值来确定映射元素是否相等

不,不是,是的,这不是一个好主意,原因正是问题中指出的原因,并且因为您不需要char*,所以可以改用 a std::string。(您可以提供自定义比较功能 - 正如 simonc 所指出的,但我建议不要这样做)

//Could these be referring to different map elements?
int i = imap["hello"];
int j = imap["hello"];
Run Code Online (Sandbox Code Playgroud)

是的,它们甚至可以引用尚不存在的元素,但它们将由创建operator[]并进行值初始化。赋值存在同样的问题:

imap["hello"] = 0;
imap["hello"] = 1;
Run Code Online (Sandbox Code Playgroud)

地图现在可以有 1 或 2 个元素。


sim*_*onc 5

您可以使用自定义比较器提供比较C字符串的映射

std::map<const char*,YourType,CstrCmp>;

bool CstrCmp::operator()(const char* a, const char* b)
{
    return strcmp(a, b) < 0;
}
Run Code Online (Sandbox Code Playgroud)