Ich stimme @Olaf zu: Verwenden Sie keine Makros, wo Funktionen verwendet werden können. Aber manchmal Umstände oder Wünsche überschreiben diesen Gedanken.
Der Präprozessor wünscht manchmal nur die richtige Anzahl von Umleitungen an der richtigen Stelle, also experimentierte ich, bis ich das bekam. Ich gebe zu, ich konnte nicht vorhersagen und ich kann nicht im Detail erklären, zumindest nicht die interessanten, nicht offensichtlichen Teile.
#define DIM 2
#define CONCAT(x,y,a,b) x ## y(a,b)
#define DOT_PRODUCT_DIM(y,a,b) CONCAT(DOT_PRODUCT_,y,a,b)
#define MULTIPLY(a, b) ((a)*(b))
#define DOT_PRODUCT_2(a, b) ( MULTIPLY((a)[0],(b)[0]) + \
MULTIPLY((a)[1],(b)[1]))
#define DOT_PRODUCT_3(a, b) ( MULTIPLY((a)[0],(b)[0]) + \
MULTIPLY((a)[1],(b)[1]) + \
MULTIPLY((a)[2],(b)[2]))
#define DOT_PRODUCT_4(a, b) ( MULTIPLY((a)[0],(b)[0]) + \
MULTIPLY((a)[1],(b)[1]) + \
MULTIPLY((a)[2],(b)[2]) + \
MULTIPLY((a)[3],(b)[3]))
#define DOT_PRODUCT(a,b) DOT_PRODUCT_DIM(DIM,a,b)
DOT_PRODUCT_DIM(2,a,b)
DOT_PRODUCT_DIM(3,a,b)
DOT_PRODUCT_DIM(4,a,b)
DOT_PRODUCT_DIM(DIM,a,b)
DOT_PRODUCT(a,b)
OUTPUT (gcc -E Toy.c
):
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])))
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])) + (((a)[2])*((b)[2])))
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])) + (((a)[2])*((b)[2])) + (((a)[3])*((b)[3])))
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])))
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])))
OUTPUT (nach nur #define DIM 3
Ändern zitieren nur die letzten beiden Zeilen der Ausgabe):
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])) + (((a)[2])*((b)[2])))
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])) + (((a)[2])*((b)[2])))
OUTPUT (nach nur #define DIM 4
ändern, Zitieren nur die letzten zwei Zeilen der Ausgabe):
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])) + (((a)[2])*((b)[2])) + (((a)[3])*((b)[3])))
((((a)[0])*((b)[0])) + (((a)[1])*((b)[1])) + (((a)[2])*((b)[2])) + (((a)[3])*((b)[3])))
OUTPUT (nach nur #define DIM 5
Ändern zitieren nur die letzten beiden Zeilen der Ausgabe):
DOT_PRODUCT_5(a,b)
DOT_PRODUCT_5(a,b)
Selbstverständlich können die Zwischen DOT_PRODUCT_number()
Makros definiert werden müssen. Die von mir bereitgestellten Beispiele funktionieren, es gibt also kein systematisches Problem, das höhere Dimensionen verhindern würde.
Ich hoffe, dass der Use Case entspricht. Du denkst nicht an unbestimmte, statisch unbekannte/unvorhersagbare hohe Anzahl von Dimensionen, oder?
Ich würde nicht denken, aber Sie könnten bedingte Logik verwenden, um alle Fälle für 'DIM' in einem kleinen Bereich zu behandeln. –
Verwenden Sie kein Makro, wo eine Funktion auch funktioniert. – Olaf
Sie könnten es mit [Boost :: Preprocessor] (http://www.boost.org/doc/libs/release/libs/preprocessor/) tun - sogar in C; dieser Code ist für den C- oder C++ - Präprozessor. Sie sollten es nicht mit Boost :: Preprocessor tun. –