不幸的是,boost 预处理器没有一种简单的方法来比较两个标记。当然,对于您的情况,您可能只需要使用一些简单的检测。这应该适用于 C99 预处理器:
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define PROBE(x) x, 1,
#define IS_VOID(x) CHECK(BOOST_PP_CAT(IS_VOID_, x))
#define IS_VOID_void PROBE(~)
但是,这不适用于括号、变量数据(例如其中带有逗号的类型)或指针。因此,以下是有效和无效的:
IS_VOID(int) // 0
IS_VOID(void) // 1
IS_VOID((void)) // Compile error
IS_VOID(std::map<int, int>) // Compile error
IS_VOID(void*) // Returns 1, but should return 0
您可以尝试解决所有这些情况,或者您可以使用更通用的比较宏(如这里的那个):
#define IS_PAREN(x) CHECK(IS_PAREN_PROBE x)
#define IS_PAREN_PROBE(...) PROBE(~)
#define IS_COMPARABLE(x) IS_PAREN( CAT(COMPARE_, x) (()) )
#define NOT_EQUAL(x, y) \
IIF(BITAND(IS_COMPARABLE(x))(IS_COMPARABLE(y)) ) \
( \
PRIMITIVE_COMPARE, \
1 EAT \
))(x, y)
#define EQUAL(x, y) COMPL(NOT_EQUAL(x, y))
#define COMPARE_void(x) x
#define IS_VOID(x) EQUAL(x, void)
可以更新它以使用 boost 预处理器组件。这应该适用于更多情况,但仍然不适用于括号(这可能不是问题)。
最后,这只是文本层面的比较,所以如果用户有 typedefed void,它会错误地返回 false:
typedef void my_void;
IS_VOID(my_void) // Returns 0
如果您正在使用检测技术,您可以允许用户将其扩展为用户定义的空隙,如下所示:
#define IS_VOID(x) CHECK(BOOST_PP_CAT(IS_VOID_, x))
#define IS_VOID_void PROBE(~)
// User-defined void
#define IS_VOID_my_void PROBE(~)