c++ - C++ 如何用宏打印可变数目的参数?

  显示原文与译文双语对照的内容
105 3

我想定义一个具有可变参数的宏,它输出每个给定参数的名称和值。

举个例子:

MACRO(x) 将打印 x = 123MACRO(x,y) 将打印 x,y = 123,666

更好的宏更易于阅读

BETTER_MACRO(x,y) 会打印x = 123, y = 666

对于一个变量,我可以使用:

#define MACRO(...) cout <<#__VA_ARGS__ <<" =" <<__VA_ARGS__ <<endl;

更重要的是,它不工作。

通过这种方式,我想到一些辅助问题。

1 ) 如何获取给定宏的变量数?2 ) 如何访问每个参数?

然后我们希望用下面的方法来定义宏。

#define BETTER_MACRO(...) {for (int i=0;i<=nb_variables;i++) {cout <<#var[i] <<var[i];}}

时间:原作者:0个回答

64 0
#define MACRO(...) function(#__VA_ARGS__, __VA_ARGS__)
//base case for template recursion when one argument remains
template <typename Arg1>
void function(const char* name, Arg1&& arg1)
{
 std::cout <<name <<" =" <<arg1 <<std::endl;
}
//recursive variadic template for multiple arguments
template <typename Arg1, typename... Args>
void function(const char* names, Arg1&& arg1, Args&&... args)
{
 const char* comma = strchr(names + 1, ',');
 std::cout.write(names, comma - names) <<" =" <<arg1;
 function(comma, args...);
}

上面有一些有点奇怪的属性,你在调用宏中包含的任何间距都将镜像在输出中。

原作者:
79 4

1 ) 如何获取给定宏的变量数?

你可以使用类似这样的元素来计算元素:( 硬编码限制):

#define COUNT_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N,.. .) N
#define COUNT(...) COUNT_N(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
//Warning: COUNT() return 1 (as COUNT(A)) :-/

2 ) 如何访问每个参数?

/* args */
#define ARG(N,.. .) ARG_##N(__VA_ARGS__)
#define ARG_1(a,.. .) a
#define ARG_2(a, b,...) b
#define ARG_3(a, b, c,.. .) c
#define ARG_4(a, b, c, d,.. .) d
#define ARG_5(a, b, c, d, e,.. .) e
#define ARG_6(a, b, c, d, e, f,.. .) f
#define ARG_7(a, b, c, d, e, f, g,.. .) g
#define ARG_8(a, b, c, d, e, f, g, h,.. .) h
原作者:
70 2

不是理想的解决方案,但:

宏本身可以接受固定数量的参数,但是每个参数都可以是带括号的列表( 尽管它只是一个文本字符串) 。

 void function_taking_varargs(...);
 #define SLIGHTLY_BETTER(x) 
 function_taking_varargs x
 SLIGHTLY_BETTER((a, b, c));
原作者:
52 0

这个工作在pre-C++11中,没有丑陋的。它使用丑陋的MACROS,它至少给出编译时错误。调用语法有点不同,但不是太多。我试图寻找类似 SEQ_ENUM的东西,但是拿了一个宏,找不到任何东西。

首先,我们将制作定制的打印 MACROS:

#define PRINT_ONE(elem) BOOST_PP_STRINGIZE(elem)" =" <<elem
#define PRINT_ONE_COMMA(r, data, elem) BOOST_PP_STRINGIZE(elem)" =" <<elem <<"," <<

接下来,一些用于打印的实用程序:

#define LAST(seq) BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), seq)
#define REST(seq) BOOST_PP_SEQ_SUBSEQ(seq, 0, BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)))

最后,我们可以迭代并打印:

#define PRINT(seq) std::cout <<BOOST_PP_SEQ_FOR_EACH(PRINT_ONE_COMMA, _, REST(seq)) PRINT_ONE(LAST(seq)) <<'n';

用法如下:

PRINT((var1)(var2)(var3))//var1 = 5, var2 = 3, var3 = 7

下面是一个 live示例。

原作者:
...