title: Generating function declaration using a macro iteration
body: <p>I'm trying to generate a function declaration using a macro </p>
  
  <pre><code>/* goal: generate int f(int a, float b) */
  template&lt;typename P&gt;
  struct ptype;
  
  template&lt;typename P&gt;
  struct ptype&lt;void(P)&gt; { typedef P type; };
  
  #define NAMEe
  #define COMMAe
  #define COMMA ,
  
  #define NAME(N) N PARAMS
  #define PARAMS(P, ...) COMMA ## __VA_ARGS__ P NAME ## __VA_ARGS__
  #define PARAM_ITER(P) P NAME
  
  #define PROTO(R, N, P)  \
    ptype&lt;void R&gt;::type N (PARAM_ITER P (,e))
  
  PROTO((int), f, (int)(a)(float)(b));
  </code></pre>
  
  <p>It will iteratively process the next <code>(name)</code> or <code>(type)</code> by <code>NAME</code> or <code>PARAMS</code> respectively, with the <code>...</code> having an empty macro argument. But GCC complains with </p>
  
  <pre><code>prototype.hpp:20:35: warning: ISO C99 requires rest arguments to be used
  </code></pre>
  
  <p>And clang complains with </p>
  
  <pre><code>ptype&lt;void (int)&gt;::type f (int aprototype.hpp:20:1: warning: varargs argument missing, but tolerated as an extension [-pedantic]
  </code></pre>
  
  <p>I think this happens because of the following</p>
  
  <pre><code>#define FOO(X, ...)
  FOO(A);
  </code></pre>
  
  <p>Because I'm not passing an argument for the <code>...</code> or each of those <code>(name)</code> or <code>(type)</code>. Is there any simple work around I can apply?</p>
  
  <hr>
  
  <p>I've now used a technique similar to the technique used by @James to find the length of a parameter list. If as second argument, instead of <code>O</code>, <code>ONT</code> is passed, I will print the comma and <code>NAME</code>. The following is the final solution:</p>
  
  <pre><code>/* goal: generate void f(int a, float b) */
  template&lt;typename P&gt;
  struct ptype;
  
  template&lt;typename P&gt;
  struct ptype&lt;void(P)&gt; { typedef P type; };
  
  #define TYPE_DO(X) X
  #define TYPE_DONT(X)
  #define TYPE_MAYBE(X, A, ...) TYPE_D ## A (X)
  
  #define COMMA_DO ,
  #define COMMA_DONT
  #define COMMA_MAYBE(A, B, ...) COMMA_D ## B
  
  #define NAME_DO NAME
  #define NAME_DONT
  #define NAME_MAYBE(A, B, ...) NAME_D ## B
  
  #define NAME(N) N PARAMS
  #define PARAMS(...) COMMA_MAYBE(__VA_ARGS__,O,O) TYPE_MAYBE(__VA_ARGS__,O,O) \
                      NAME_MAYBE(__VA_ARGS__,O,O)
  #define PARAM_ITER(P) P NAME
  
  #define PROTO(R, N, P)  \
    ptype&lt;void R&gt;::type N (PARAM_ITER P (D,ONT))
  </code></pre>
  
  <p>Test:</p>
  
  <pre><code>#define STR1(X) #X
  #define STR(X) STR1(X)
  
  int main() {
    // prints correctly
    std::cout &lt;&lt; STR(PROTO((int), f, (int)(a)(float)(b)));
  }
  </code></pre>