根据是否定义了另一个宏来评估宏
Evaluate macro depending if another macro is defined
以下preprocessor-basedidentifier-to-string查找table:
#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
宏正确处理 table 中的现有键,并将给定值替换为字符串文字。
但是对于 non-existing 键,它将键替换为字符串文字。
有没有办法让它用给定的常量代替 non-existing 键,而不会导致 compile-time 错误,并且所有这些都在预处理阶段?
因此,例如,LOOKUP(c)
和 LOOKUP(whatever)
都应替换为 "undefined"
,而不会在包含的生成文件中出现 c
或 whatever
.
密钥的名称不应输出到已编译的二进制文件中,因此理想情况下,它们永远不会被编译器看到。
这是一个简单的解决方案,虽然有点老套。通过将 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
以下preprocessor-basedidentifier-to-string查找table:
#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
宏正确处理 table 中的现有键,并将给定值替换为字符串文字。
但是对于 non-existing 键,它将键替换为字符串文字。
有没有办法让它用给定的常量代替 non-existing 键,而不会导致 compile-time 错误,并且所有这些都在预处理阶段?
因此,例如,LOOKUP(c)
和 LOOKUP(whatever)
都应替换为 "undefined"
,而不会在包含的生成文件中出现 c
或 whatever
.
密钥的名称不应输出到已编译的二进制文件中,因此理想情况下,它们永远不会被编译器看到。
这是一个简单的解决方案,虽然有点老套。通过将 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