(如何)我可以在c++中使用字符串数组作为标识符

(How) can I use an array of strings as identifiers in C++?

本文关键字:字符串 数组 标识符 如何 我可以 c++      更新时间:2023-10-16

我正在研究这个项目,我需要解析一个包含两列表的文本文件,该表由左侧的名称和右侧的值组成。

现在,我需要将它们写入控制表中的特定位置,这些位置使用十六进制地址标识;在我不能编辑的头文件中,它们被定义为:

#define HARRY_POTTER 0x3A

然后有一个写入函数,它接受一个地址和一个值,并将其写入存储位置(这个函数也不在我的控制范围内)。因此,调用这个

write(0x3A, 7);

与调用

的结果相同
write(HARRY_POTTER, 7);

由于头文件中的定义。

现在,我已经完成了解析,它基本上为我提供了作为字符串的左列名称(例如,"HARRY_POTTER")和作为整数的右列值。

我想知道的是,如果有任何方法可以使用这个字符串,"哈利波特"作为写函数中的标识符;实际上是将字符串转换为标识符,这样我就可以循环遍历整个已解析值数组,它会自动将它们写入与左列中的字符串/名称匹配的地址。

这可能吗?如果是,怎么做?

不,这是不可能的。原因是您从文件中读取的字符串仅在运行时已知,而预处理在编译时进行,因此HARRY_POTTER必须已经被替换。实际上,在程序被编译之后,根本不存在任何标识符。

您可能希望它引入从std::string s到您已定义的常量的映射。例如:

std::unordered_map<std::string, int> mapping = {{"HARRY_POTTER", HARRY_POTTER},
                                                {"RON_WEASLEY", RON_WEASLEY}};
当然,这些常量将在编译时被替换,所以这就相当于:
std::unordered_map<std::string, int> mapping = {{"HARRY_POTTER", 0x3A},
                                                {"RON_WEASLEY", 0x7C}};

则可以用

调用write
write(mapping.at(key), 7);

其中key为值为"HARRY_POTTER"的字符串

(这个答案更适合评论,但我仍在努力提高声誉…)

我同意Joseph的观点,在c++ 11中使用std::unordered_map或者在c++ 03中使用std::map。

我只是想补充一点,在这种情况下,你可以通过一点宏魔术使代码更易于维护和编写。

/* The stringify macro converts x to "x" at compile-time. */
#define _stringify(x) # x
#define stringify(x) _stringify(x)
/* Macro easing the assignment of { "String", value } */
#define STR_VAL(x) { stringify(x), (x) }
/* Now you can write the assignment code as follows */
std::unordered_map<std::string, int> mapping = {
    STR_VAL(HARRY_POTTER),
    STR_VAL(RON_WEASLEY),                                                          
    STR_VAL(ALBUS_BRIAN_WULFRIC_PERCIVAL_DUMBLEDORE)
};

这意味着如果#define HARRY_POTTER的值改变了,映射代码将在您重新编译时自动更新。