Boost logo

Boost Users :

Subject: Re: [Boost-users] Looping through variadic macro arguments
From: Florian Lindner (mailinglists_at_[hidden])
Date: 2016-03-22 15:35:03


On Mon, 21 Mar 2016 10:39:52 -0400
Edward Diener <eldiener_at_[hidden]> wrote:

> On 3/21/2016 4:55 AM, Florian Lindner wrote:
> > Hey,
> >
> snipped ...
> >
[...]
> >
> >
> > Any comments on that? How to do it better? Maybe without a helper
> > macro PRINT?
> > I'm a bit surprised I have to use r-1 to get 1 for the first
> > argument.
>
> The PRINT macro is fine. Almost all Boost PP looping constructs use a
> helper macro like that.
>
> In real life code I would name all macros in uppercase and give them
> a very distinct name to reduce clashes with other potential C++
> identifiers and macros.

Sure!
 
> Look at BOOST_PP_SEQ_FOR_EACH_I to get the actual argument index
> instead of using 'r'.
>
> That 'r' in your code above is actually 2,3, and 4 is just luck. The
> 'next available BOOST_PP_FOR repetition' as described in the doc just
> happened to be 2,3, and 4 but could theoretically have been any PP
> number each time and is not related to the index of each argument.

Ok, try to use FOR_EACH_I, but ran into compilation errors:

#define PRINT(r, data, i, elem) \
  cout << "Argument " << i << ": " << elem << endl;

#define vmacro(expr, ...) \
  cout << "Expression: " << #expr << endl; \
  BOOST_PP_SEQ_FOR_EACH_I(PRINT, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)); \

but:

% g++ -std=c++11 -g3 -rdynamic -ldl test.cpp && ./a.out :(
test.cpp: In function 'void f(int)':
test.cpp:127:27: error: 'PRINT' was not declared in this scope
   BOOST_PP_SEQ_FOR_EACH_I(PRINT, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)); \
                           ^
test.cpp:159:3: note: in expansion of macro 'vmacro'
   vmacro(1-2, 5, 6);
   ^
test.cpp:127:34: error: expected primary-expression before ',' token
   BOOST_PP_SEQ_FOR_EACH_I(PRINT, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)); \
                                  ^
test.cpp:159:3: note: in expansion of macro 'vmacro'
   vmacro(1-2, 5, 6);
   ^
In file included from /usr/include/boost/preprocessor/variadic/to_seq.hpp:17:0,
                 from test.cpp:11:
test.cpp:127:36: error: expression cannot be used as a function
   BOOST_PP_SEQ_FOR_EACH_I(PRINT, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)); \
                                    ^
test.cpp:159:3: note: in expansion of macro 'vmacro'
   vmacro(1-2, 5, 6);
   ^
test.cpp:127:73: error: 'BOOST_PP_SEQ_FOR_EACH_I' was not declared in this scope
   BOOST_PP_SEQ_FOR_EACH_I(PRINT, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)); \
                                                                         ^
test.cpp:159:3: note: in expansion of macro 'vmacro'
   vmacro(1-2, 5, 6);
   ^

boost 1.60, gcc 5.3.0.

The same code, using FOR_EACH works (only the argumentens of PRINT were altered.

Thanks!

Florian


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net