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

tml*_*len 3 c++ preprocessor c-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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

valueA
valueB
KEY_c
Run Code Online (Sandbox Code Playgroud)

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

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

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

有没有办法让它用给定的常量替换不存在的键,而不会导致编译时错误,并且全部在预处理阶段进行?

例如,LOOKUP(c)LOOKUP(whatever)应该全部替换为"undefined", 而不出现cwhatever出现在包含的生成文件中。

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

ric*_*ici 5

这是一个简单但有些棘手的解决方案。通过定义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;
}
Run Code Online (Sandbox Code Playgroud)

对coliru进行测试