Ich habe zwei Makros FOO2
und FOO3
:
#define FOO2(x,y) ...
#define FOO3(x,y,z) ...
Ich möchte ein neues Makro FOO
wie folgt definieren:
#define FOO(x,y) FOO2(x,y)
#define FOO(x,y,z) FOO3(x,y,z)
Dies funktioniert jedoch nicht, da Makros die Anzahl der Argumente nicht überladen.
Ohne Modifikation FOO2
und FOO3
ist es eine Möglichkeit , ein Makro zu definieren FOO
(mit __VA_ARGS__
oder auf andere Weise) , um die gleiche Wirkung des Versands erhalten FOO(x,y)
zu FOO2
, und FOO(x,y,z)
zu FOO3
?
c
macros
c-preprocessor
Andrew Tomazos
quelle
quelle
Antworten:
Einfach wie:
Wenn Sie also diese Makros haben:
Wenn Sie einen vierten wollen:
Natürlich, wenn Sie definieren
FOO2
,FOO3
undFOO4
wird die Ausgabe durch die der definierten Makros ersetzt werden.quelle
EXPAND
in @ Étiennes Link erwähnte verwendet werden soll, rufen Sie ihn im GrundeGET_MACRO
so auf#define FOO(...) EXPAND(GET_MACRO(__VA_ARGS__, FOO3, FOO2, FOO1)(__VA_ARGS__))
und er sollte auf die richtige Anzahl von Argumenten in msvc erweitert werden.ISO C++11 requires at least one argument for the "..." in a variadic macro
. Um dies zu beheben, fügen Sie nach dem letzten Parameter in der Definition von FOO (...) ein nicht verwendetes Argument (oder sogar nur ein Komma) hinzu:#define FOO(...) GET_MACRO(__VA_ARGS__, FOO3, FOO2, UNUSED)(__VA_ARGS__)
( Siehe es läuft auf Coliru ).Um die Antwort des Netzcodierers zu ergänzen, KÖNNEN Sie dies mit Hilfe der GCC-
##__VA_ARGS__
Erweiterung mit einem Makro mit 0 Argumenten tun :quelle
#define FOO0 _Pragma("error FOO0 not allowed")
?FOO0
Wenn der Anruf nicht in qt + mingw32 funktioniert,FOO0
wird derFOO1
-std=c99
oder zu verwenden-std=c11
. Sie müssen verwenden-std=gnu99
oder-std=gnu11
stattdessen_0, ##__VA_ARGS__
durch_0 __VA_OPT__(,) __VA_ARGS__
der neue Weg ist, dies zu tun.Hier ist eine allgemeinere Lösung:
Definieren Sie Ihre Funktionen:
Jetzt können Sie
FOO
mit 2, 3 und 4 Argumenten verwenden:Einschränkungen
Ideen
Verwenden Sie es für Standardargumente:
Verwenden Sie es für Funktionen mit einer möglichen unendlichen Anzahl von Argumenten:
PS:
__NARG__
wird von Laurent Deniau & Roland Illig hier kopiert: https://groups.google.com/group/comp.std.c/browse_thread/thread/77ee8c8f92e4a3fb/346fc464319b1ee5?pli=1quelle
__NARG_I_
erscheint völlig unnötig und überflüssig. Es fügt nur einen zusätzlichen Schritt und Verwirrung hinzu. Ich empfehle, es vollständig zu löschen und__NARG__
stattdessen nur zu definieren als :#define __NARG__(...) __ARG_N(__VA_ARGS__,__RSEQ_N())
._VFUNC_
: einfach löschen. Definieren Sie dann_VFUNC
als:#define _VFUNC(name, n) name##n
anstelle von#define _VFUNC(name, n) _VFUNC_(name, n)
.Ich habe das nur selbst recherchiert und bin hier darauf gestoßen . Der Autor hat die Standardargumentunterstützung für C-Funktionen über Makros hinzugefügt.
Ich werde versuchen, den Artikel kurz zusammenzufassen. Grundsätzlich müssen Sie ein Makro definieren, das Argumente zählen kann. Dieses Makro gibt 2, 1, 0 oder einen beliebigen Bereich von Argumenten zurück, die es unterstützen kann. Z.B:
Dazu müssen Sie ein weiteres Makro erstellen, das eine variable Anzahl von Argumenten akzeptiert, die Argumente zählt und das entsprechende Makro aufruft. Ich habe Ihr Beispielmakro genommen und es mit dem Beispiel des Artikels kombiniert. Ich habe die FOO1-Aufruffunktion a () und die FOO2-Aufruffunktion a mit Argument b (natürlich gehe ich hier von C ++ aus, aber Sie können das Makro auf was auch immer ändern).
Also wenn du hast
Der Präprozessor erweitert das auf
Ich würde definitiv den Artikel lesen, den ich verlinkt habe. Es ist sehr informativ und er erwähnt, dass NARG2 nicht mit leeren Argumenten funktioniert. Er folgt dieser bis hier .
quelle
Hier ist eine kompaktere Version der obigen Antwort . Mit Beispiel.
Lauf:
Beachten Sie, dass beides vorhanden ist
_OVR
und_OVR_EXPAND
möglicherweise redundant aussieht. Der Präprozessor muss jedoch das_COUNT_ARGS(__VA_ARGS__)
Teil erweitern, das ansonsten als Zeichenfolge behandelt wird.quelle
Vielleicht können Sie dieses Makro verwenden, um die Anzahl der Argumente zu zählen .
quelle
Hier ist ein Spin-off von Evgeni Sergeevs Antwort. Dieser unterstützt auch keine Argumentüberladungen !
Ich habe dies mit GCC und MinGW getestet. Es sollte mit alten und neuen Versionen von C ++ funktionieren. Beachten Sie, dass ich es für MSVC nicht garantieren würde ... Aber mit einigen Optimierungen bin ich zuversichtlich, dass es auch damit funktionieren könnte.
Ich habe dies auch so formatiert, dass es in eine Header-Datei eingefügt wird (die ich macroutil.h genannt habe). Wenn Sie dies tun, können Sie diesen Header einfach einfügen, was auch immer Sie für die Funktion benötigen, und nicht auf die Unangenehmkeit achten, die mit der Implementierung verbunden ist.
quelle
Dies scheint bei GCC, Clang und MSVC gut zu funktionieren. Es ist eine bereinigte Version einiger der Antworten hier
quelle
#define func0() foo
? Die aktuelle Version behandelt diesen Fall leider nicht.