2015-09-04 12 views
6

fand ich eine Frage zeigt, wie Makros basierend auf der Anzahl von Argumenten zu überlasten: Overloading Macro on Number of Arguments__VA_ARGS__ Expansion mit MSVC

Aber wie sie sagen, es funktioniert nicht MSVC verwenden, weil MSVC __VA_ARGS__ in ein einziges Token erweitert anstelle eines Liste der Argumente (arg1, arg2, arg3).

Sie zeigen auf eine andere Frage, wo eine Arbeit gegeben ist: MSVC doesn't expand __VA_ARGS__ correctly Aber überhaupt nicht erklärt, so kann ich es nicht an meinen eigenen Fall anpassen, da ich es nicht verstehen kann.

Könnten Sie bitte erläutern, wie diese Problemumgehung funktioniert?

+0

Ich denke, der verknüpfte Beitrag ist nicht korrekt. Ich denke, die richtige Lösung ist 'G (...) F (EXPAND (__ VA_ARGS__))' – LPs

+0

@LPs, dachte ich auch, aber versuchen Sie es. –

+0

@JohnBollinger Ich bin zu Linux drin, um MSVC in die Hände zu bekommen :). Ernsthaft, ich habe keine MSVC, um es zu testen. Lassen Sie OP versuchen Sie es – LPs

Antwort

9

Die Abhilfemaßnahme in Frage lautet:

#define EXPAND(x) x 
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 
#define G(...) EXPAND(F(__VA_ARGS__)) 

Die Idee ist, dass angesichts einer bestehenden variadische Makro F():

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 

stattdessen gewünschten variadische Wrapper Makro wie in diesem Fall des Schreibens, ...

#define G(...) F(__VA_ARGS__) 

... schreiben Sie G() mit der Verwendung der zusätzlichen EXPAND() Makro. Die tatsächliche Definition von F() ist nicht der Punkt, und insbesondere spielt es für dieses Beispiel keine Rolle, dass die Makroexpansion keinen gültigen C-Code erzeugt. Sein Zweck besteht darin, das Verhalten des Präprozessors in Bezug auf Makroargumente zu demonstrieren. Insbesondere zeigt es, dass, obwohl MSVC __VA_ARGS__ zu einem einzelnen Token in einem Variadic-Makro erweitert, das um eine doppelte Erweiterung erzwungen werden kann.

beispielsweise die Abhilfe Definition verwendet wird, der Vorprozessor erste erweitert ...

G(1, 2, 3) 

... bis ...

EXPAND(F(1, 2, 3)) 

... wo die 1, 2, 3 als behandelt wird einzelnes Token. Diese Tokenisierung spielt jedoch keine Rolle mehr, wenn der Präprozessor erneut nach zusätzlichen Ersetzungen sucht: Er sieht die 1, 2, 3 als separate Argumente für das Makro F() und erweitert diese, um das Argument für das Makro EXPAND() zu erzeugen, das es einfach durch es ersetzt.

Wenn Sie es seltsam finden, dass dies wie vorgesehen funktioniert, aber die Version ohne EXPAND() nicht funktioniert (in MSVC), haben Sie Recht.

+0

danke für deine Hilfe! Ich werde mir das später ansehen! – Virus721

+0

Es funktioniert, danke. Ich verstehe es jetzt auch besser. Das Aufrufen des Makros, in dem die Argumente mithilfe eines anderen Makros erweitert werden sollen, bewirkt, dass der Compiler die Argumente korrekt erweitert. – Virus721

+0

Eigentlich ist mein Fall ein bisschen anders. Ich würde gerne überladen, basierend auf der Anzahl der Argumente: 1 Arg -> Methode für 1 Arg, 2 Args -> Methode für 2 Args. ABER: Ich möchte auch, dass> 2 Argumente -> Methode für 2 Args + Va Args, da die beiden Überladungen für mein Makro eine Arg-Liste nach den obligatorischen Parametern haben können. Das verursacht mir ein Problem, denn wenn ich meine Methode mit> 2 Argumenten aufrufen, wird das 3. Argument als Methodenname verwendet, was falsch ist. – Virus721