3

我之前问过以下问题,但该解决方案似乎不适用于这种特殊情况。

如何使用 Boost Preprocessor 多次打印逗号

我正在尝试有条件地扩展包含逗号的宏。这是一个说明问题的示例:

#define TEST(...)\
    BOOST_PP_REPEAT( \
        BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
        MACRO, \
        BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))

#define MACRO(z, n, data) BOOST_PP_IF(1,MACRO_CONTAINING_COMMA(z, z),MACRO_CONTAINING_COMMA(z, z))

#define MACRO_CONTAINING_COMMA(_NAME, _NAME2) _NAME TIBRA_EATEN_COMMA() _NAME2

#define EATEN_COMMA BOOST_PP_IF(1,BOOST_PP_COMMA,BOOST_PP_TUPLE_EAT())
TEST(1,2,3,4)

这扩展到

BOOST_PP_IIF BOOST_PP_IIF BOOST_PP_IIF BOOST_PP_IIF

当它应该扩展到

0,0 1,1 2,2 3,3

4

2 回答 2

5

您可以通过首先选择它然后调用它来延迟调用宏:

#define TEST(...)\
    BOOST_PP_REPEAT( \
        BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
        MACRO, \
        BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))

#define MACRO(z, n, data) BOOST_PP_IF(1,MACRO_CONTAINING_COMMA,MACRO_CONTAINING_COMMA)(n, n)

#define MACRO_CONTAINING_COMMA(_NAME, _NAME2) _NAME EATEN_COMMA _NAME2

#define EATEN_COMMA BOOST_PP_IF(1,BOOST_PP_COMMA,BOOST_PP_TUPLE_EAT())()

看它工作

IF调用扩展到没有调用的宏或在调用时丢弃参数的东西。选择一个后,最后的括号会使用所需的参数调用它,而不会妨碍逗号。

除此之外,我更改zn和。由于某些部分是多余的,您可以在此处找到更简单的版本。TIBRA_EATEN_COMMA()EATEN_COMMA

于 2014-07-16T01:15:50.233 回答
0

事实证明,您可以在没有__VA_ARGS__. 在这个简单的例子中,我在函数的模板参数中使用了一个逗号toString<int,int>() Working demo

#include <boost/lexical_cast.hpp>
#include <boost/preprocessor.hpp>
#include <iostream>
#include <string>

#define SEQUENCE (1)(2)(3)(4)(5)(6)(7)(8)(9)(10)

#define IGNORE_ARG(arg)
#define GET_NAME(data) BOOST_PP_SEQ_ELEM(0, data)
#define GET_BELOW(data) BOOST_PP_SEQ_ELEM(1, data)

#define PARSE_SEQUENCE(r, data, elem)                  \
    BOOST_PP_IF(                                       \
        BOOST_PP_GREATER_EQUAL(elem, GET_BELOW(data)), \
            GET_NAME(data), IGNORE_ARG)                \
    (elem)

#define SKIP_NUMBERS_BELOW(name, below)                \
    BOOST_PP_SEQ_FOR_EACH(PARSE_SEQUENCE, (name)(below), SEQUENCE)

#define TEST(name) SKIP_NUMBERS_BELOW(name, 4)

#define MACRO_CONTAINING_COMMA(N) toString<N, 2 * N>() <<

template <int a, int b> // whatever, I just need a comma here.
std::string toString() {
    return boost::lexical_cast<std::string>(a) + ":" + boost::lexical_cast<std::string>(b) + " ";
}

int main() {
    std::cout << TEST(MACRO_CONTAINING_COMMA) "\n";
}
于 2020-06-02T16:21:14.347 回答