2016-10-30 1 views
-2
#define STRIP0 0 
#define STRIP1 1 
#define STRIP2 2 
#define STRIP3 3 
#define PINS0 2,3,4 
#define PINS1 5,6,7 
#define PINS2 8,9,10 
#define PINS3 11,12,13 

#define PINS(STRIP) { (STRIP) == (STRIP0) ? PINS0 :\ 
         (STRIP) == (STRIP1) ? PINS1 :\ 
         (STRIP) == (STRIP2) ? PINS2 :PINS3} 

jetzt, wenn, wenn ich eine Funktion aufrufen, die foo(int,int,int); 3 alle Argumente vom Typ int nimmt wie folgt foo(PINS1); dann erstellt die Funktion und funktioniert wie erwartet (alle Argumente als bestanden, wenn der #define war ersetzt durch "5,6,7")Makros Funktionsargumente wählen

aber wenn ich das Makro für die Auswahl der Satz von Pins wie foo(PINS(STRIP1)); verwenden, dann geht die Argumentauswahl drunter und drüber. In diesem speziellen Fall wird die Liste der fehlerhaften Argumente "7,12,13" und für foo(PINS(STRIP0)); wird "4,12,13". Es gibt ein Muster, das ich sehe, aber ich habe nicht das Fachwissen, um zu sagen und zu korrigieren, was bei der Kompilierung passiert Zeit.

+0

Wenn Sie das 'PINS' Funktion-ähnliche Makro verwenden, haben Sie zwei Probleme: Das erste ist die geschweifte Klammern, die Sie um den gesamten Ausdruck haben. Die zweite ist, dass anstelle der Übergabe mehrerer Argumente übergeben Sie ein einziges Argument, denn dann Komma wird nicht zu einem Argumenttrennzeichen, sondern zum Kommaausdruck. Sie sollten Ihre Verwendung von Makros überdenken, vielleicht verwenden Sie stattdessen einen Inline-Funktions-Wrapper? Oder zumindest das Makro modifizieren, vielleicht die Funktion als Argument nehmen und den Aufruf innerhalb des Makros "body" haben? –

+0

Warum schreibst du nicht einfach ein "if/else" – Danh

+0

@Someprogrammerdude Ich werde die geschweiften Klammern entfernen und die Frage bearbeiten, aber es hatte keinen Effekt in der Ausgabe. Wenn ich dies 'foo (PINS1);' (wie in der Frage angegeben) die Funktion nimmt die 3 Zahlen als Argumente selbst, die mich zu der Annahme, dass das Komma als Ausdruck nicht statt Compiler erkannte, dass es gibt 3 Argumente und das führte Deshalb ging es weiter. das ist der Grund, warum ich dachte, ein Makro zu tun, das die 'PINS0' oder' PINS1' auswählt, funktioniert, aber es hat nicht funktioniert. Ihr Vorschlag, die Funktion als Argument im Makro zu haben, ist wahrscheinlich, was Krzaq schlägt –

Antwort

0

Imo du leidest Lesbarkeit viel durch die Verwendung von Makros dafür. Aber hier ist, wie ich dies tun würde:

#define STRIP0 0 
#define STRIP1 1 
#define STRIP2 2 
#define STRIP3 3 
#define PINS0 2,3,4 
#define PINS1 5,6,7 
#define PINS2 8,9,10 
#define PINS3 11,12,13 

#define CONCAT_HELP(A, B) A ## B 

#define CONCAT(A, B) CONCAT_HELP(A, B) 

#define PINS(FUNC,STRIP) FUNC(CONCAT(PINS, STRIP)) 

jetzt, würden Sie dies wie folgt aufrufen:

PINS(foo, STRIP0); 

demo

Sie benötigen zwei Dereferenzierungsebenen, wegen der Art, Makro Ersatz funktioniert (here ist eine eingehende Erklärung). Mit nur #define CONCAT(A,B) A ## B, CONCAT(PINS,STRIP0) würde PINSSTRIP0 schaffen, die hier keinen Sinn macht.


Der Vollständigkeit halber, wenn Sie erwarten, dass diese Werte mit der Laufzeit verwenden (von denen Sie keine Hinweise auf die Frage gegeben haben), können Sie mit einer Hilfsfunktion Vorlage gehen, die über den Streifen Wert wechseln würde:

template<typename Func> 
void pins(Func f, int strip) 
{ 
    switch(strip){ 
    case 0: f(PINS0); break; 
    case 1: f(PINS1); break; 
    case 2: f(PINS2); break; 
    case 3: f(PINS3); break; 
    } 
} 

demo

und, wenn Sie C++ 17 zur Verfügung:

constexpr tuple<int,int,int> params[] = { 
    make_tuple(PINS0), 
    make_tuple(PINS1), 
    make_tuple(PINS2), 
    make_tuple(PINS3) 
}; 

template<typename Func> 
void pins(Func f, int strip) 
{ 
    apply(f, params[strip]); 
} 

demo

obwohl zu diesem Zeitpunkt die Hilfsfunktion nicht mehr benötigt wird.

+1

Ich brauchte auf jeden Fall meinen Kaffee. Gute Antwort, aber vielleicht ist es wichtig zu erklären, warum * eine Zwischenexpansion erforderlich ist. Das OP scheint nicht sehr versiert zu sein. – StoryTeller

+0

@StoryTeller hinzugefügt. – krzaq

+1

Das Ziel, das ich erreichen möchte, ist, dass jeder PINS0-Satz einem anderen Satz physischer Pin-Verbindungen entspricht, die sich zur Laufzeit nicht ändern und als Argumente an verschiedene Funktionen übergeben werden müssen das Problem, diese Definitionen überall zu ändern, das ist alles! Ich werde versuchen deine Antwort sieht aus wie es funktionieren sollte @StoryTeller Ich bin nicht sehr versiert sicher, danke an alle für ihre Hilfe ;-) –