Makro-Funktion mit mehreren Zeilen für die parameter?
In C++,
Ich muss definiert ein makro.
Das makro nehmen würde als parameter einen "block" der code.
Können wir sicher mehrere Zeilen code als parameter einer makro-Funktion?
Frage ich mich, wenn :
- ist der folgende code gültig ist, die Gültigkeit definiert der standard, wie in "cross-platform"?
- gibt es eine bessere Möglichkeit, das gleiche zu tun (ich kann nicht mit template-Funktion gibt, denn ich brauche den Kontext).
#define MY_MACRO( expr ) DOSOMETHING( (expr) ); DOANOTHERTHING( (expr) ); //etc...
int my_function() {
int o = RandomNumber();
MY_MACRO(
int k = AFunction();
k++;
AnotherFunction( k + o ); //here I need to keep the context of the call
);
}
Können wir nicht verwenden, funktoren, weil wir müssen, um Zugriff auf den Kontext des Aufrufs.
Wir können nicht lambda (snif), weil wir uns mit einem alten compiler, die das nicht bieten (und wir können es nicht ändern).
- was ist die Verwendung dieses Makros?
- Hast du es versuchen ? Was ist passiert ? Meine Vermutung ist, dass jeder Ausdruck "parameter", die Sie übergeben werden müssen, eingeschlossen in
()
. - Danke für den edit-Paul, konnte nicht finden, wie man die Anzeige rechts. @CharlesB : Es erzeugt code, legen Sie die Ausdrücke Parameter in mehrere Teil des generierten Codes. Das problem bezieht sich auf: können wir sicher mehrere Zeilen code als parameter einer makro-Funktion?
- R: Wir versuchen jetzt, aber die Frage ist mehr, wenn es durch eine Norm definiert (mit mehreren Zeilen für ein makro) und wenn es cross-platforum.
- vielleicht kann es helfen mit Antworten, wenn Sie erklären, was meinst du mit Kontext. Tun Sie, zum Beispiel, müssen alle dem Staat, in den der Anrufer innerhalb
DOSOMETHING
undDOANOTHERTHING
? Wenn nicht, können Sie nicht einkapseln, was Sie brauchen innerhalb eines funktors, die Sie weitergeben können, um diese? - Als ich Hinzugefügt, das können wir einfach nicht verwenden funktoren oder lambda. Finden Sie den aktualisierten code. Die DOSOMETHING und DOANOTHERTHING makro hier nicht revelant auf die Frage, weil es die Tatsache, dass wir die Wiederverwendung mehr als einmal die
expr
wichtig ist. Soweit kann ich aus mehreren Zeilen code, ich bin gut mit dem makro.
Du musst angemeldet sein, um einen Kommentar abzugeben.
16.3/9:
Also die multi-line-makro-Aufruf im Allgemeinen ist in Ordnung. Natürlich, wenn
DOSOMETHING
undDOANOTHERTHING
nicht vorstellen, Klammern für Rahmen, dann ist dein Beispiel nicht neu definieren wirdk
.Edit:
Der übliche Weg ist, um zu erfassen, welche Variablen Sie benötigen in der Funktor, wie eine lambda hat. Das einzige, was ein lambda-Ausdruck machen kann, dass ein Funktor kann nicht "capture everything", ohne es aus, aber wer schreibt die lambda kann sehen, welche Variablen, die Sie verwenden, so dass nur die Bequemlichkeit, geben Sie Sie alle aus, wenn Sie musste. In deinem Beispiel:
Können Sie erfassen auch die Variablen per Referenz (in der Regel mit einem Zeiger als Datenelement eher als eine Referenz, so dass der Funktor kopieren-zugeordnet).
Wenn Sie von "Kontext", Sie bedeuten zum Beispiel, dass die makro-argument und/oder die makro-Körper enthalten, ein
break
odergoto
, und daher muss innerhalb der lexikalischen Gültigkeitsbereich des Aufrufers, dann können Sie nicht verwenden ein Funktor oder ein lambda-Ausdruck. Für Schande 😉den Weg machen, damit es funktioniert (zumindest bei gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu9)), ist verwenden Sie geschweifte Klammern { } umschließen ist für das makro.
Ist ein gutes Beispiel:
Ich denke, Sie müssen verwenden Sie zusätzliche Klammern, um Ihre Ausdrücke zu sehen, wie ein einzelnes argument, das nicht kaputt zu bekommen durch den Präprozessor, d.h. tun Sie es eher so:
obwohl ich noch nicht wirklich versucht.
In C++ können Sie sollte Verwendung eines funktors! 😉
[](){ int k = AFunction(); ++k, AnotherFunction( k ); }
Das Hauptproblem, dass ich sehe ist, dass
expr
ist nicht ein Ausdruck überhaupt. Es enthält sogar eine Erklärung. Offensichtlich sind Sie gehen zu müssen, ein problem mit zwei Variablenk
definiert inmy_function
.Wenn du kannst C++0x (z.B. VS2010, GCC4.6) dann können Sie mit lambda-Kontext zu erfassen. Nicht, dass müssten Sie erfassen Kontext für solch einen einfachen Fall, und Sie müssen auch keine Vorlagen, das makro braucht nur ein
std::function<void(void)>
.Eines Makros mit mehreren Zeilen für die parameter ist auch in Ordnung, bei mehreren Argumenten, wird es sogar ermöglicht, "Komma" drin sein, aber ich stark descourage mit "Kommas" beause, wenn es nicht ambiguos zu einer Maschine ist es sicherlich ambiguos auf den Menschen: