如何将BOOST_PP_IF与BOOST_PP_LPAREN结合使用?

时间:2014-07-19 09:42:24

标签: c++ boost nested c-preprocessor boost-preprocessor

我试图有条件地将宏扩展到"("或" 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())

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您可以通过抽象出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,并且工作几乎相同方式(不完整的类函数宏名称将传递给参数列表,直到它完成)。