c++ - 根据是否定义了另一个宏来评估宏

标签 c++ c-preprocessor preprocessor

以下基于预处理器的标识符到字符串查找表:

#include <iostream>

// included generated file
#define KEY_a valueA
#define KEY_b valueB
///////

#define LOOKUP_(_key_) KEY_ ## _key_
#define QUOTE_(_str_) #_str_
#define EXPAND_AND_QUOTE_(_str_) QUOTE_(_str_)

#define LOOKUP(_key_) EXPAND_AND_QUOTE_(LOOKUP_(_key_))

int main() {
    std::cout << LOOKUP(a) << std::endl;
    std::cout << LOOKUP(b) << std::endl;
    std::cout << LOOKUP(c) << std::endl;
}

输出:

valueA
valueB
KEY_c

第一个#defines 来自编译前由外部脚本生成的#included header 。

LOOKUP 宏正确处理表中的现有键,并将给定值替换为字符串文字。

但是对于不存在的键,它将键替换为字符串文字。

有没有办法让它用给定的常量代替不存在的键,而不会导致编译时错误,并且所有这些都在预处理阶段?

因此,例如,LOOKUP(c)LOOKUP(whatever) 都应替换为 "undefined",而无需 cwhatever 出现在包含的生成文件中。

key 的名称不应输出到已编译的二进制文件中,因此理想情况下,它们永远不会被编译器看到。

最佳答案

这是一个简单但有点老套的解决方案。通过将 KEY_x 定义为两个元素的列表(第一个元素将被忽略),它允许添加默认值:

#include <iostream>

// included generated file
#define KEY_a _,valueA
#define KEY_b _,valueB
///////

#define LOOKUP_(key) KEY_ ## key
#define QUOTE_(_,str,...) #str
#define EXPAND_AND_QUOTE_(...) QUOTE_(__VA_ARGS__)

#define LOOKUP(key) EXPAND_AND_QUOTE_(LOOKUP_(key),undefined)

int main() {
    std::cout << LOOKUP(a) << std::endl;
    std::cout << LOOKUP(b) << std::endl;
    std::cout << LOOKUP(c) << std::endl;
}

测试coliru

关于c++ - 根据是否定义了另一个宏来评估宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57432071/

相关文章:

c++ - 将 libnoise 库链接到 Visual Studio 2010 中的项目时遇到问题

c# - 短按和长按处理

c - #include ansi C 中的图像

c++ - 如果类型(不)相等,C++ 是否可以有条件地编译代码?

qt - Qt 项目中的版本号

c++ - 将自定义工具添加到工具链以在编译前删除 UTF-8 BOM

c++ - 帧率差异和 UDP 连接

c++ - 在 C++ 中使用指向一系列整数的指针

c++ - VS2013忽略杂注警告禁用

c# - #if(DEBUG) 和 log4net 行号源/运行时不匹配