Как мне объединить BOOST_PP_IF с BOOST_PP_LPAREN?

Я пытаюсь условно расширить макрос до «(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())

Что я делаю неправильно?

2

Решение

Вы можете заставить порядок оценки соответствовать ожидаемому, абстрагируя ветви 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()

поскольку THEN а также ELSE не полные имена, ветви не будут расширены до IF расширен; когда он возвращается, значение объединяется с PAS_ сформировать новое действительное определение и будет расширяться в то время.

Вы также можете параметризовать THEN а также ELSE Макросы и делают эту технику более общей (и IMO более элегантной): передача параметров к неполному имени, по существу, формирует thunk, и работает почти так же (неполное имя, похожее на функцию макроса, будет передано вокруг плюс список параметров, пока не будет завершено ).

1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector