2013-05-04 4 views
2

Est-il possible de définir quelque chose comme ceci:Macro surcharge

#define FOO(x, y) BAR() 
#define FOO(x, sth, y) BAR(sth) 

pour que ceci:

FOO("daf", sfdas); 
FOO("fdsfs", something, 5); 

est traduit à ceci:

BAR(); 
BAR(something); 

?

Éditer: En fait, BAR sont des méthodes de ma classe. Désolé de ne pas avoir dit ça avant (je ne pensais pas que c'était pertinent).

Répondre à la question de DPJ:

class Testy 
{ 
    public: 
    void TestFunction(std::string one, std::string two, std::string three) 
    { 
     std::cout << one << two << three; 
    } 
    void AnotherOne(std::string one) 
    { 
     std::cout << one; 
    } 
    void AnotherOne(void) 
    { 
     std::cout << ""; 
    } 
}; 

#define PP_NARG(...) PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) 
#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__) 
#define PP_ARG_N(_1, _2, _3, N, ...) N 
#define PP_RSEQ_N() 3, 2, 1, 0 

// macro for exactly 2 arguments 
#define FOO_2(_1, _2) AnotherOne() 
// macro for exactly 3 arguments 
#define FOO_3(_1, _2, _3) AnotherOne(_2) 

// macro selection by number of arguments 
#define FOO_(N) FOO_##N 
#define FOO_EVAL(N) FOO_(N) 
#define TestFunction(...) FOO_EVAL(PP_NARG(__VA_ARGS__))(__VA_ARGS__) 

Et appelez:

Testy testy; 
testy.TestFunction("one", "two", "three"); // line 9 

sortie du compilateur:

Avertissement 1 Avertissement C4003: pas assez de paramètres réels pour macro 'PP_ARG_N' principale. cpp 9

Avertissement 2 avertissement C4003: pas assez de paramètres réels de macro main.cpp 'foo_' 9

d'erreur 3 erreur C2039: 'foo_': ne fait pas partie de main.cpp 'Testy' 9

+2

Pourquoi utiliser des macros? – 0x499602D2

+0

Il est possible de le laisser développer 'BAR (sfdas);' et 'BAR (quelque chose, 5);' respectivement. Est-ce acceptable? Les macros ne peuvent pas "ignorer" le dernier paramètre, mais elles peuvent rejeter la première. – leemes

+0

Voir aussi http://stackoverflow.com/questions/3850421/can-i-define-variadic-c-preprocessor-macros-with-va-args-in-the-middle-instead – leemes

Répondre

10

Edition - ---------------------------------------------- Regardez ici-- -------------------------------------------------- ------------->

(Overloading macro on number of arguments)

// functions, or macros, .... 
void bar(){} 
void bar(int){} 

#define EXPAND(X) X // for MSVC10 compatibility 

// compute number of (variadic) macro arguments 
// from http://groups.google.com/group/comp.std.c/browse_thread/thread/77ee8c8f92e4a3fb/346fc464319b1ee5?pli=1 
#define PP_NARG(...) EXPAND(PP_NARG_(__VA_ARGS__, PP_RSEQ_N())) 
#define PP_NARG_(...) EXPAND(PP_ARG_N(__VA_ARGS__)) 
#define PP_ARG_N(_1, _2, _3, N, ...) N 
#define PP_RSEQ_N() 3, 2, 1, 0 


// macro for exactly 2 arguments 
#define FOO_2(_1, _2) bar() 
// macro for exactly 3 arguments 
#define FOO_3(_1, _2, _3) bar(_2) 

// macro selection by number of arguments 
#define FOO_(N) FOO_##N 
#define FOO_EVAL(N) FOO_(N) 
#define FOO(...) EXPAND(FOO_EVAL(EXPAND(PP_NARG(__VA_ARGS__)))(__VA_ARGS__)) 

int main() 
{ 
    int something = 42; 
    FOO("daf", sfdas); 
    FOO("fdsfs", something, 5); 
} 

sortie du préprocesseur:

void bar(){} 
void bar(int){} 

int main() 
{ 
    int something = 42; 
    bar(); 
    bar(something); 
} 

Edit2: On dirait VS2010 a quelques problèmes avec __VA_ARGS__ et le remplacement macro.

MISE À JOUR: C'est ... un bug ?? (Voir aussi this SO question):

#define MACRO2(PARAM0, PARAM1, ...) arg 0: >PARAM0< arg 1: >PARAM1< \ 
    additional args: >__VA_ARGS__< 
#define MACRO1(...) MACRO2(__VA_ARGS__, OTHERARG_0, OTHERARG_1) 

MACRO1(ARG0, ARG1); 

sortie préprocesseur:

arg 0: >ARG0, ARG1< arg 1: >OTHERARG_0< additional args: >OTHERARG_1<; 

Pour une solution de contournement, voir le lien SO question. J'ai mis à jour la réponse originale (code) ci-dessus et l'ai testé avec MSVC10 -> fonctionne maintenant.

+0

J'ai modifié ma question - 'BAR' est une méthode d'une classe et votre solution ne fonctionne pas pour cela (le compilateur dit quelque chose à propos de 'FOO_PP_NARG' n'étant pas un membre de 'MyClass'). – NPS

+0

@NPS Cela ne devrait pas avoir d'importance.Compilateur? Erreur exacte msg? – dyp

+0

Compilateur VS2010, le reste j'ai fourni dans ma question. – NPS