【问题标题】:String concatenate to self in preprocessor字符串在预处理器中连接到自身
【发布时间】:2018-03-24 23:55:30
【问题描述】:

我发现了很多用 C 或 C++ 预处理器连接字符串的问题和答案;例如this question(但还有更多)。

我找不到的是是否可以连接到同一个字符串。更清楚地说,是这样的

#define MY_STRING "Hello"
#define MY_STRING MY_STRING " world"
// Now MY_STRING is "Hello world"

如果我必须在“运行时”期间编写它,我会写类似

char my_string[80];
strcpy(my_string, "Hello");

strcat(my_string, " world"); // <- similar to this operation, but in preprocessor

但是请注意,这不是我想要做的;我希望在编译时执行连接。

这可能吗?还是定义是“不可变的”?

这个问题与 C 或 C++ 的特定风格无关;如果这只能用两种语言中的一种或只能用某些特定的编译器来实现,请在答案中指定它

编辑:正如 Lightness Races in Orbit 部分猜测的那样,我的问题主要围绕条件编译以及可扩展性展开。

至于条件编译,我目前做的是

#if COND_1
    #define STR_COND_1 " val1"
#else
    #define STR_COND_1 ""
#endif
#if COND_2
    #define STR_COND_2 " val2"
#else
    #define STR_COND_2 ""
#endif

#define STR STR_COND_1 STR_COND_2

这里的问题是,当条件变得太多时,这会导致错误(很容易忘记一个),而串联则没有这个问题。

至于可扩展性,我的意思是如果我必须添加另一个将其字符串添加到 STR 的模块(例如,COND_3),我必须手动将其添加到 STR 定义中,而通过连接它是自动的.

现在,这些例子真的很简单,所以忘记它是很困难的,但是当你有一个项目时,这些东西分散在很多文件中,忘记一个变量很容易,而且会浪费很多时间

【问题讨论】:

  • 只需使用const std::string s = "Hello World" 并继续捕捉更大更好的鱼。
  • @Ron 也许我不够清楚,但我不希望它在程序期间完成,而是在编译时......而且你可以将 s 连接到其他字符串吗?跨度>
  • @Ron:这个问题是有效的。世界并不都围绕运行时的动态分配。预处理器是一个有用的工具,可以提出有关它的问题。
  • 这个答案的第二部分有一个绝妙的技巧:stackoverflow.com/a/46019437/1566221

标签: c++ c


【解决方案1】:

You can't redefine a preprocessor macro。所以,没有。

如果您不介意一次性完成所有操作,可以将两个 文字 连接起来,这样:

#define MY_STRING "hello" " world"

或者使用不同的名称。这是一个示例,正如我所料,引入了一个条件,这是您从问题中省略的问题的真正症结:

#define MY_STRING_BASE "hello"

#ifdef FOO
#define MY_STRING MY_STRING_BASE " world"
#else
#define MY_STRING MY_STRING_BASE
#endif

【讨论】:

  • 是的,我需要它的主要原因是条件编译和可扩展性。我在问题中添加了一些内容以进一步澄清它
  • 好吧,我的答案没有改变 - 不过感谢您改进问题!
【解决方案2】:

不能重新定义宏。我没有想到任何完全适合您需要的内置解决方案,但是如何使用简单的正则表达式来生成所有条件的列表?

假设每个条件宏都以STR_COND_ 开头,然后正则表达式对所有文件运行应生成所有条件的列表:

(STR_COND_\w+)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    相关资源
    最近更新 更多