7

使用 C 字符串作为映射键有什么问题吗?

std::map<const char*, int> imap;

地图中元素的顺序无关紧要,因此可以使用std::less<const char*>.

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

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

它说它们仅在某些情况下被池化,因此使用字符串文字访问地图元素似乎不是一个好主意:

//Could these be referring to different map elements?
int i = imap["hello"];
int j = imap["hello"];

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

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

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

4

3 回答 3

8

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

不,不是,是的,由于问题中指出的原因,这不是一个好主意,因为你不需要char*,你可以使用 astd::string代替。(您可以提供自定义比较功能 - 正如 simonc 所指出的那样,但我不建议这样做)

//Could these be referring to different map elements?
int i = imap["hello"];
int j = imap["hello"];

是的,它们甚至可以引用尚不存在的元素,但它们将被创建并被operator[]初始化。分配也存在同样的问题:

imap["hello"] = 0;
imap["hello"] = 1;

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

于 2012-12-13T11:31:39.273 回答
7

您可以提供带有自定义比较器的地图,用于比较 C 字符串

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

bool CstrCmp::operator()(const char* a, const char* b) const
{
    return strcmp(a, b) < 0;
}
于 2012-12-13T11:33:19.380 回答
1

首先,为了引入对映射键的排序,您需要定义一个“小于”比较。地图表示如果两个元素都不小于另一个元素,则两个元素是“等价的”。将 char* 用于映射键是一个坏主意,因为您需要在映射之外的某个地方进行内存管理。

在大多数实际情况下,当您查询地图时,您的键不会是文字。

另一方面,如果您自己维护一个字符串字面量池并为每个字面量分配一个 ID,您可以将这些 ID 用于映射键。

总而言之,我不会依赖微软说“在某些情况下可能会汇集文字”。如果你用文字填充地图,并且如果你用文字作为键查询地图,你不妨使用枚举作为键。

于 2012-12-13T11:34:33.313 回答