【问题标题】:(How) can I use an array of strings as identifiers in C++?(如何)我可以在 C++ 中使用字符串数组作为标识符吗?
【发布时间】:2014-09-02 02:42:59
【问题描述】:

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

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

#define HARRY_POTTER 0x3A

然后有一个写入函数,它接受一个地址和一个值并将其写入一个存储位置(这个函数也是我无法控制的)。所以,调用这个

write(0x3A, 7);

与调用它的结果相同

write(HARRY_POTTER, 7);

由于头文件中的定义。

现在,我已经完成了解析,它基本上给了我左列,名称,作为一个字符串(例如,“HARRY_POTTER”),右列,值,作为一个整数。

我想知道是否有任何方法可以使用这个字符串“HARRY_POTTER”作为写入函数中的标识符;本质上是将字符串转换为标识符,这样我就可以遍历整个解析值数组,它会自动将它们写入与字符串匹配的地址/左列中的名称。

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

【问题讨论】:

  • 你被介绍给std::map了吗?

标签: c++ string c-preprocessor identifier


【解决方案1】:

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

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

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"

【讨论】:

  • 调用 write 应该首先检查密钥是否存在。如果它不存在,那么它应该抛出异常或返回错误代码(尽管此代码实际上已经抛出 std::out_of_range 异常)。
  • 啊,有道理!非常感谢,我会使用你提到的无序地图。谢谢!
【解决方案2】:

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

我同意 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 的值发生变化,您的映射代码将在您重新编译时自动更新。

【讨论】:

    猜你喜欢
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 2021-03-13
    • 2018-04-14
    • 2021-09-24
    相关资源
    最近更新 更多