Boost logo

Boost Users :

Subject: Re: [Boost-users] Looping through variadic macro arguments
From: Edward Diener (eldiener_at_[hidden])
Date: 2016-03-22 20:53:06


On 3/22/2016 3:35 PM, Florian Lindner wrote:
> 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__)); \

What is that final '\' about ?

Please show the header files being included.

>
>
> 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