我正在尝试有条件地将宏扩展为“(a”或“b”),但这样做的幼稚方法在我使用的任何一个编译器(Microsoft C / C++和NDK编译器)上均不起作用)。例:

// This works on both compilers, expands to ( a ) as expected
#define PARENS_AND_SUCH BOOST_PP_IF(1, BOOST_PP_LPAREN() a BOOST_PP_RPAREN(), b)

// MSVC: syntax error/unexpected end of file in macro expansion
// NDK: unterminated argument list
#define PARENS_AND_SUCH BOOST_PP_IF(1, BOOST_PP_LPAREN() a, b)

// Desired expansion: ( a
// MSVC expansion: ( a, b )
// NDK: error: macro "BOOST_PP_IIF" requires 3 arguments, but only 2 given
#define PARENS_AND_SUCH BOOST_PP_IF(1, BOOST_PP_LPAREN() a, b BOOST_PP_RPAREN())

我究竟做错了什么?

最佳答案

您可以通过将IF的分支抽象为子定义来强制求值顺序与期望的顺序一致,并延迟它们的扩展,直到条件返回分支为止:

#define PARENS_AND_SUCH BOOST_PP_CAT(PAS_, BOOST_PP_IF(1, THEN, ELSE))
#define PAS_THEN BOOST_PP_LPAREN() a
#define PAS_ELSE b BOOST_PP_RPAREN()

由于THENELSE不是全名,因此在扩展IF之前不会扩展分支。当它返回时,该值与PAS_组合以形成一个新的有效定义,并在那时扩展。

您还可以参数化THENELSE宏,并使此技术更通用(并且IMO更为优雅):将参数传递给不完整的名称本质上会形成一个thunk,并且工作方式几乎相同(类似于函数的不完整宏名称将是传递加号列表,直到完成)。

关于c++ - 如何将BOOST_PP_IF与BOOST_PP_LPAREN结合?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24838928/

10-11 20:41