2010-02-20 5 views
5

Vu:C l'argument macro 'stockage'

#define f(x, y) (x+y) 
#define g(x, y) (x*y) 
#define A 1, 2 
#define B 2, 3 

int main() { 
    int a = f(A); 
    int b = g(A); 
    int c = f(B); 
    int d = g(B); 
} 

qui ne fonctionne pas,

comment puis-je le faire fonctionner? L'idée de base est que j'ai une liste d'arguments que je veux passer à deux macros différentes, sans répéter la liste des arguments longs à chaque fois.

Existe-t-il un moyen de le faire? [Vous pouvez modifier f & g; vous êtes même invités à modifier A & la façon dont j'appelle les macros. Les seules exigences sont les suivantes: 1) la liste arguemnt ne peut apparaître qu'une seule fois 2) il ne peut pas être codé en dur ... pour que je puisse appeler les macros avec des arguments différents

Si vous êtes solution ne tout à fait travailler mais «presque fonctionne» (pour vous la définition de presque), je voudrais l'entendre aussi, peut-être que je peux le fudge au travail.

Merci!

Édition: f & g doit être des macros. Ils capturent les noms des symboles et les manipulent.

+0

Si vous modifiez les exigences de votre question initiale, s'il vous plaît fournir un exemple approprié qui montre ce que vous voulez réellement. –

Répondre

3

EDIT: Une version non modifiée qui fonctionne avec A et B

#define f(x, y) (x+y) 
#define g(x, y) (x*y) 
#define A 1, 2 
#define B 2, 3 

#define APPLY2(a, b) a b 
#define APPLY(a, b) APPLY2(a, (b)) 

int main(int argc, char* argv[]) 
{ 
    int x= APPLY(f, A); 
    int y= APPLY(f, B); 
    int z= APPLY(g, A); 
    int d= APPLY(g, B); 

    return 0; 
} 
+0

Ceci est ingénieux. Quiconque comprend comprendra cette réponse. – anon

+0

Pourquoi l'indirection supplémentaire? '#define APPLIQUE (a, b) a (b)' fonctionne aussi bien. –

+0

@Chris, ça ne marche pas comme ça. J'oublie le rason exact, mais MSVC se plaint certainement à ce sujet. – MSN

4

Vous pouvez le faire:

static int f(int x, int y) { return (x+y); } 
static int g(int x, int y) { return (x*y); } 
#define A 1, 2 
#define B 2, 3 

Si vous utilisez un compilateur C qui a soutenu une directive inline non standard, vous pouvez éliminer la surcharge d'un appel de fonction. Et si vous utilisiez C++,

template<T> T f(T x, T y) { return (x+y); } 
template<T> t g(T x, T y) { return (x*y); } 
#define A 1, 2 
#define B 2, 3 

qui fonctionnerait à peu près de la même manière que la solution de macro C voulue.

Si f et gdoit être macros, il n'y a aucune façon avec le préprocesseur C pour passer plusieurs arguments aux macros sans virgule réelle apparaissant sur le site d'invocation. Pour ce faire, vous devez ajouter un niveau de pré-préprocesseur au-dessus de le préprocesseur C.

+0

Belle solution. De plus, même sans la directive inline, tant que vous utilisez la directive statique sur les fonctions, l'optimisation des compilateurs s'introduira automatiquement de toute façon. –

+0

"une directive inline non standard". D'ailleurs, si elle soutenait la norme, elle insisterait probablement sur quelque chose d'aussi simple.Nous savons que le questionneur utilise C99, puisque sa fonction principale n'a pas de déclaration de retour, mais est supposée avoir un comportement défini ;-) –

0

Peut-être que c'est ce que vous voulez:

#include<iostream> 
using namespace std; 

#define A 1, 2 

template <typename T> 
inline T f(T a, T b) { return a + b; } 

int main() 
{ 
    cout << f(A) << endl; 
    return 0; 
} 
+1

La question concerne C, n'est ce pas? –

4

Si vous utilisez C99, vous pouvez utiliser le compound initialiser syntax pour le faire en adoptant plusieurs arguments en un seul tableau:

#define f(a) (a[0]+a[1]) 
#define g(a) (a[0]*a[1]) 
#define A ((int[]) {1, 2}) 
#define B ((int[]) {2, 3}) 

supports GCC cette syntaxe littérale composée en mode C89 et C++.

+0

Thx pour trier ceci :) – mre