Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are a couple of ways to solve the problem. First, you can use typed expression in the macro so you can parse the type. So the <code>CREATE_OBJECT_IMPL</code> would be called like this:</p> <pre><code>CREATE_OBJECT_IMPL(Object, (Arg1) arg1, (Arg2) arg2) </code></pre> <p>Here are some macros that will retrieve the type and strip off the type:</p> <pre><code>#define EAT(x) #define REM(x) x #define STRIP(x) EAT x #define PAIR(x) REM x </code></pre> <p>These macros work like this. When you write <code>STRIP((Arg1) arg1)</code> it will expand to <code>arg1</code>. And when you write <code>PAIR((Arg1) arg1)</code> it will expand to <code>Arg1 arg1</code>. Now next, you will want to do is to apply these macros to each argument that is passed in, so here is a simple <code>APPLY</code> macro that will let you do that for up to 8 arguments:</p> <pre><code>/* This counts the number of args */ #define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N #define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) /* This will let macros expand before concating them */ #define PRIMITIVE_CAT(x, y) x ## y #define CAT(x, y) PRIMITIVE_CAT(x, y) /* This will call a macro on each argument passed in */ #define APPLY(macro, ...) CAT(APPLY_, NARGS(__VA_ARGS__))(macro, __VA_ARGS__) #define APPLY_1(m, x1) m(x1) #define APPLY_2(m, x1, x2) m(x1), m(x2) #define APPLY_3(m, x1, x2, x3) m(x1), m(x2), m(x3) #define APPLY_4(m, x1, x2, x3, x4) m(x1), m(x2), m(x3), m(x4) #define APPLY_5(m, x1, x2, x3, x4, x5) m(x1), m(x2), m(x3), m(x4), m(x5) #define APPLY_6(m, x1, x2, x3, x4, x5, x6) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6) #define APPLY_7(m, x1, x2, x3, x4, x5, x6, x7) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7) #define APPLY_8(m, x1, x2, x3, x4, x5, x6, x7, x8) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8) </code></pre> <p>Then you can define the <code>CREATE_OBJECT_IMPL</code> like this:</p> <pre><code>#define CREATE_OBJECT_IMPL(ObjectType, ...) \ ObjectType* Create##ObjectType(APPLY(PAIR, __VA_ARGS__)) \ { \ ObjectType* object = new ObjectType(); \ [...] \ object-&gt;Init(this, APPLY(STRIP, __VA_ARGS__)); \ [...] \ return object; \ } </code></pre> <p>Of course, you might need some workarounds for these macros, if you use them on visual studio. Of course, a better solution is to write a templated function. So you would call your <code>CreateObject</code> like this:</p> <pre><code>ObjectType* obj = CreateObject&lt;ObjectType&gt;(arg1, arg2, arg3); </code></pre> <p>In C++11, you can use varidiac templates like this:</p> <pre><code>template&lt; typename ObjectType, typename... Args &gt; ObjectType* CreateObject(Args... args) { ObjectType* object = new ObjectType(); [...] object-&gt;Init(this, args...); [...] return object; } </code></pre> <p>But if your compiler doesn't support varidiac templates, you can use the <a href="http://www.boost.org/doc/libs/1_54_0/libs/preprocessor/doc/index.html">Boost.PP</a> to generate overloads for up to 10 arguments(or more if you need to):</p> <pre><code>#define GENERATE_OBJS_EACH(z, n, data) \ template&lt;class ObjectType, BOOST_PP_ENUM_PARAMS_Z(z, n, class Arg)&gt; \ ObjectType* CreateObject(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, arg)) \ { \ ObjectType* object = new ObjectType(); \ [...] \ object-&gt;Init(this, BOOST_PP_ENUM_PARAMS_Z(z, n, arg)); \ [...] \ return object; \ } /* Generate CreateObject template for up to 10 arguments */ BOOST_PP_REPEAT_FROM_TO_1(1, 10, GENERATE_OBJS_EACH, ~) </code></pre> <p>Edit: Heres are the workarounds you would need to get the above macros to work in msvc:</p> <pre><code>/* This counts the number of args */ #define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N #define NARGS_MSVC_WORKAROUND(x) NARGS_SEQ x #define NARGS(...) NARGS_MSVC_WORKAROUND((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)) /* This will let macros expand before concating them */ #define PRIMITIVE_CAT(x, y) x ## y #define CAT_MSVC_WORKAROUND(x) PRIMITIVE_CAT x #define CAT(x, y) CAT_MSVC_WORKAROUND((x, y)) /* This will call a macro on each argument passed in */ #define APPLY(macro, ...) APPLY_MSVC_WORKAROUND(CAT(APPLY_, NARGS(__VA_ARGS__)), (macro, __VA_ARGS__)) #define APPLY_MSVC_WORKAROUND(m, x) m x ... </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload