Erzeugende Funktion Erklärung mit Hilfe eines makro-iteration

Ich versuche zu generieren, die Funktionsdeklaration mit einem makro

/* goal: generate int f(int a, float b) */
template<typename P>
struct ptype;

template<typename P>
struct ptype<void(P)> { 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<void R>::type N (PARAM_ITER P (,e))

PROTO((int), f, (int)(a)(float)(b));

Wird es iterativ mit der Bearbeitung des nächsten (name) oder (type) durch NAME oder PARAMS bzw. mit der ... mit einer leeren makro-argument. Aber GCC beschwert sich mit

prototype.hpp:20:35: warning: ISO C99 requires rest arguments to be used

Und clang beschwert sich mit

ptype<void (int)>::type f (int aprototype.hpp:20:1: warning: varargs argument missing, but tolerated as an extension [-pedantic]

Ich denke, dies geschieht aufgrund der folgenden

#define FOO(X, ...)
FOO(A);

Weil ich mich nicht übergeben eines Arguments für die ... oder jede dieser (name) oder (type). Gibt es keine einfache Arbeit um die ich mich bewerben kann?


Hab ich ja jetzt eine Technik ähnlich dem Verfahren von @James zu finden, die Länge der parameter-Liste. Wenn als zweites argument, statt O, ONT übergeben wird, werde ich drucken Sie das Komma und die NAME. Das folgende ist die endgültige Lösung:

/* goal: generate void f(int a, float b) */
template<typename P>
struct ptype;

template<typename P>
struct ptype<void(P)> { 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<void R>::type N (PARAM_ITER P (D,ONT))

Test:

#define STR1(X) #X
#define STR(X) STR1(X)

int main() {
  //prints correctly
  std::cout << STR(PROTO((int), f, (int)(a)(float)(b)));
}
Schreibe einen Kommentar