我想要一系列宏来替换以下代码
#ifdef FOO
return true;
#else
return false;
#endif
像
return MAGICLY_EXPANDING_IFDEFINED_MACRO(FOO);
您可以猜到,有很多 FOO,足以将 4 行缩小为 1 行会很酷。但实际上它会用一行替换一个怪物 switch 语句。
最佳答案
在 C++ 中,defined
的行为仅针对条件包含( #if
和 #elif
)指定。所以你不能以任何其他方式使用它。
(相关规则见标准第16.1节)
但是,如果您想检测空字符串的 #define
宏,则不需要 defined()
,您可以这样做:
#include <iostream>
/* this matches */
#define FOO
/* this will not */
#undef BAZ
/* nor will these */
#define BAR 0
//#define BAR 1
#define STRINGIZE(x) (#x)
#define EXPAND_IF_DEFINED(y) (!*STRINGIZE(y))
int main()
{
std::cout << +EXPAND_IF_DEFINED(FOO) << '\n'
<< +EXPAND_IF_DEFINED(BAR) << '\n'
<< +EXPAND_IF_DEFINED(BAZ) << '\n';
}
警告,
-D
选项不会是空字符串。要处理这种情况,您可以使用类似#define IS_MACRO_DEFINED_OR_ONE(y) (!*STRINGIZE(y) || '1'==*STRINGIZE(y))
一个更强大的测试将是
#define IS_MACRO_DEFINED_NOT_TO_ITSELF(y) strcmp(#y, STRINGIZE(y))
由于文字是编译时常量,编译器可能会在编译为常量
strcmp
或 true
期间优化该 false
调用。您还可以制作 constexpr
的 strcmp
版本以供使用。关于c++ - 将 defined(X) 返回为 true 或 false 的宏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26286684/