Variadic macros

Is there a way to write a macro like this:

#define G(x1, x2, ... , xn) f(x1), f(x2), ... , f(xn)

Or do I need to define this for each individual n?

C ++ 0x answers are fine.

Edit: I ask how to create a macro of this form, not a macro, which usually takes a variable number of arguments.

Purpose:: I can do something like the following:

#define MAKE_TUPLE(x1, x2, ... , xn) mytuple<decltype((x1)), decltype((x2)), ... , decltype((xn))>{x1, x2, ... , xn}

Thus, this one mytuplecan be created without any movements and copies, or unnecessary references to temporary sections that could be created in place using the aggregate structure.

+3
source share
3 answers

, Boost.Preprocessor:

#include <boost/preprocessor.hpp>

#define G(args) BOOST_PP_SEQ_FOR_EACH_I(G_GENF, x, args)
#define G_GENF(r, data, i, elem) \
    BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(i, 0)) f(elem)

:

G((a))
G((b)(c))
G((d)(e)(f))

:

f(a)
f(b) , f(c)
f(d) , f(e) , f(f)

G(a, b, c), , , , , , , . , . :

// Utility for counting the number of args in the __VA_ARGS__ pack:
#define PP_NARGS(...) PP_NARGS2(__VA_ARGS__, PP_NARGS_COUNT())
#define PP_NARGS2(...) PP_NARGS_IMPL(__VA_ARGS__)
#define PP_NARGS_IMPL(x1, x2, x3, N, ...) N
#define PP_NARGS_COUNT() 3, 2, 1, 0, ERROR

// Macros to delegate to concrete, defined-arity implementations:
#define XF(count, ...) XF_IMPL (count, __VA_ARGS__)
#define XF_IMPL(count, ...) XF_ ## count (__VA_ARGS__)

// Defined-arity implementations:
#define XF_1(x1)         f(x1)
#define XF_2(x1, x2)     f(x1), f(x2)
#define XF_3(x1, x2, x3) f(x1), f(x2), f(x3)

// Delegation macro; this is the only macro you need to call from elsewhere:
#define G(...) XF(PP_NARGS(__VA_ARGS__), __VA_ARGS__)    

:

G(a)
G(b, c)
G(d, e, f)

:

f(a)
f(b), f(c)
f(d), f(e), f(f)

, , , , , . ( C99/++ 0x, .)

+5

: [ ]. , mytuple , , .

. , .

. , ( ) ( , , , ). , " ", .

template<typename ...T>
mytuple<T...> make_tuple(T&&... t) {
  return mytuple<T...>{std::forward<T>(t)...};
}

decltype, X

  • Prvalues ​​ X
  • Xvalues ​​ X
  • Lvalues ​​ X&

  • Prvalues ​​ X
  • Xvalues ​​ X&&
  • Lvalues ​​ X&

- , , , prvalues ​​ X . mytuple<T&&...> , , .

  • Prvalues ​​ X&&
  • Xvalues ​​ X&&
  • Lvalues ​​ X&
+5

, Boost Preprocessor ++ 98.

However, macros are evil and best avoided.

Instead, consider doing things like

Type const values[] = {x1, x2, x3, ... xn};

for( int i = 0;  i < countOf( values );  ++i )
{
    f( values[i] );
}

Greetings and hth.

0
source

All Articles