Hello,
another question: I was expecting that the line
BOOST_PP_SEQ_FOR_EACH_I(PRINT_ARGUMENT,, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__));
in a macro #define vm(expr, ...) expands to nothing, when the the macro is called with just one argument vm(false), but it fails, only when called with just one argument:
% g++ -std=c++11 -g3 test.cpp
test.cpp: In function 'void f(int)':
test.cpp:109:51: error: expected primary-expression before '<<' token
std::cerr << " Argument " << i << ": " << elem << std::endl;
^
/usr/include/boost/preprocessor/seq/for_each_i.hpp:85:66: note: in expansion of macro 'PRINT_ARGUMENT'
# define BOOST_PP_SEQ_FOR_EACH_I_M_I(r, macro, data, seq, i, sz) macro(r, data, i, BOOST_PP_SEQ_HEAD(seq))
^
test.cpp:140:1: note: in expansion of macro 'assertion'
assertion(!true);
^
Is there any way to make it work like that?
Thanks a lot!
Florian
The code looks like that:
#define PRINT_ARGUMENT(r, data, i, elem) \
std::cerr << " Argument " << i << ": " << elem << std::endl;
#define assertion(expr, ...) if (!(expr)) { \
std::cerr << "Assertion in " << __FILE__ << ":" << __LINE__ \
<< ", failed expression: " << #expr << std::endl; \
std::cout << BOOST_PP_VARIADIC_SIZE(__VA_ARGS__) << std::endl; \
BOOST_PP_SEQ_FOR_EACH_I(PRINT_ARGUMENT,, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)); \
std::cerr.flush(); \
std::cout.flush(); \
assert(false); \
} \
On Tue, 22 Mar 2016 20:53:06 -0400
Edward Diener
On 3/22/2016 3:35 PM, Florian Lindner wrote:
On Mon, 21 Mar 2016 10:39:52 -0400 Edward Diener
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