在宏内取消字符串化

Posted

技术标签:

【中文标题】在宏内取消字符串化【英文标题】:Unstringize inside a Macro 【发布时间】:2021-05-23 10:18:23 【问题描述】:

在宏内部,我可以使用字符串化操作符#:

#define STRINGIZE(name) #name

cout << STRINGIZE(SomeClass) << endl; // Prints "SomeClass"

是否可以在宏中执行相反的操作,unstringize?怎么样?

例如:

#define RUN_FUNCTION(name) UNSTRINGIZE(name)();

void myFunction 
  cout << "Hello!" << endl;


RUN_FUNCTION("myFunction") // Prints "Hello!"

如果不是,有什么原因吗?

【问题讨论】:

我很好奇您为什么要这样做,因为"myFunction" 需要是编译时字符串常量(预处理器可以访问的唯一类型的字符串)? 我可以肯定这是做不到的。一个原因可能是没有人需要它。会有一些有趣的问题需要解决。 其实我不需要这个,我只是好奇。在阅读了 OP 想要从用户输入调用函数的问题后,我问自己是否有 unstringify 运算符 不,这是不可能的。它只会使预处理器更加复杂(在宏语言中引入两种类型,“随便什么”和“请只使用字符串”),而没有明显的需要。另外,取消字符串化并非易事(UNSTRINGIZE("\x9f") 是什么?) FWIW,我实际上几天前遇到了这个问题。一些整数数据被写成一个字符串,我想在编译时操作那个整数,所以我想去掉引号(代码库太大而不能简单地更改整数)。我已经知道这是不可能的,所以不要浪费时间。你们太沉迷于动机原因了;有时人们只是出于好奇而提问。 【参考方案1】:

不,这是不可能的。 C++ 预处理器不能以任何方式将标记分解成更小的标记。

您到底想做什么?几乎可以肯定有更好的方法。

【讨论】:

【参考方案2】:

[由评论推荐] 预处理发生在编译之前,也就是运行时之前。你需要反射来做到这一点,而无需定义自己的规则,这需要某种形式的元数据,而 C++ 没有。

我找不到在哪里,但我最近在某个地方看到(可能是here,但根据Wikipedia,它已被推迟)反射可能会在未来某个时候出现在 C++ 中,因此可能会有前景在那里。

【讨论】:

以上是关于在宏内取消字符串化的主要内容,如果未能解决你的问题,请参考以下文章

在宏内使用 Qt4 和 CMake 的 find_package 时出现问题

VIM - 宏内的多次搜索破坏了预期的逻辑

C语言中单井号(#)和双井号(##)在宏语句中的应用

宏定义中##和#的作用

在宏中拆分字符串

在宏中连接字符串 - C++