Est-il un moyen d'obtenir des paramètres optionnels avec C++ Macros? Une sorte de surcharge serait sympa aussi. Il ne semble pas comme si il y est? Je ne pourrais pas trouver la méthode, de toute façon.
Merci à l'avance!
Est-il un moyen d'obtenir des paramètres optionnels avec C++ Macros? Une sorte de surcharge serait sympa aussi. Il ne semble pas comme si il y est? Je ne pourrais pas trouver la méthode, de toute façon.
Merci à l'avance!
Voici une façon de le faire. Il utilise la liste des arguments à deux reprises, d'abord pour former le nom de l'aide de la macro, puis de passer les arguments à l'aide de la macro. Il utilise un truc standard pour compter le nombre d'arguments de la macro.
enum
{
plain = 0,
bold = 1,
italic = 2
};
void PrintString(const char* message, int size, int style)
{
}
#define PRINT_STRING_1_ARGS(message) PrintString(message, 0, 0)
#define PRINT_STRING_2_ARGS(message, size) PrintString(message, size, 0)
#define PRINT_STRING_3_ARGS(message, size, style) PrintString(message, size, style)
#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
#define PRINT_STRING_MACRO_CHOOSER(...) \
GET_4TH_ARG(__VA_ARGS__, PRINT_STRING_3_ARGS, \
PRINT_STRING_2_ARGS, PRINT_STRING_1_ARGS, )
#define PRINT_STRING(...) PRINT_STRING_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
int main(int argc, char * const argv[])
{
PRINT_STRING("Hello, World!");
PRINT_STRING("Hello, World!", 18);
PRINT_STRING("Hello, World!", 18, bold);
return 0;
}
Cela rend plus facile pour l'appelant de la macro, mais pas l'écrivain.
Avec un grand respect pour Derek Ledbetter pour sa réponse et avec mes excuses pour faire revivre une vieille question.
Obtenir une compréhension de ce qu'elle faisait et ramasser ailleurs sur la capacité de précéder l' __VA_ARGS__
avec ##
m'a permis de venir avec une variation...
// The multiple macros that you would need anyway [as per: Crazy Eddie]
#define XXX_0() <code for no arguments>
#define XXX_1(A) <code for one argument>
#define XXX_2(A,B) <code for two arguments>
#define XXX_3(A,B,C) <code for three arguments>
#define XXX_4(A,B,C,D) <code for four arguments>
// The interim macro that simply strips the excess and ends up with the required macro
#define XXX_X(x,A,B,C,D,FUNC, ...) FUNC
// The macro that the programmer uses
#define XXX(...) XXX_X(,##__VA_ARGS__,\
XXX_4(__VA_ARGS__),\
XXX_3(__VA_ARGS__),\
XXX_2(__VA_ARGS__),\
XXX_1(__VA_ARGS__),\
XXX_0(__VA_ARGS__)\
)
Pour des non spécialistes comme moi qui trébuchent sur la réponse, mais ne voit pas bien comment il fonctionne, je vais étape par étape du traitement proprement dit, en commençant avec le code suivant...
XXX();
XXX(1);
XXX(1,2);
XXX(1,2,3);
XXX(1,2,3,4);
XXX(1,2,3,4,5); // Not actually valid, but included to show the process
Devient...
XXX_X(, XXX_4(), XXX_3(), XXX_2(), XXX_1(), XXX_0() );
XXX_X(,1, XXX_4(1), XXX_3(1), XXX_2(1), XXX_1(1), XXX_0(1) );
XXX_X(,1,2, XXX_4(1,2), XXX_3(1,2), XXX_2(1,2), XXX_1(1,2), XXX_0(1,2) );
XXX_X(,1,2,3, XXX_4(1,2,3), XXX_3(1,2,3), XXX_2(1,2,3), XXX_1(1,2,3), XXX_0(1,2,3) );
XXX_X(,1,2,3,4, XXX_4(1,2,3,4), XXX_3(1,2,3,4), XXX_2(1,2,3,4), XXX_1(1,2,3,4), XXX_0(1,2,3,4) );
XXX_X(,1,2,3,4,5, XXX_4(1,2,3,4,5), XXX_3(1,2,3,4,5), XXX_2(1,2,3,4,5), XXX_1(1,2,3,4,5), XXX_0(1,2,3,4,5) );
Qui devient le sixième argument...
XXX_0();
XXX_1(1);
XXX_2(1,2);
XXX_3(1,2,3);
XXX_4(1,2,3,4);
5;
PS: Supprimer le #define pour XXX_0 pour obtenir une erreur de compilation [ie: si un non-argument de l'option n'est pas autorisée].
PPS: Serait agréable d'avoir l'invalide situations (ex: 5) être quelque chose qui donne une meilleure erreur de compilation pour le programmeur!
PPPS: je ne suis pas un expert, donc je suis très heureux d'entendre les commentaires (bon, mauvais ou autres)!
C++ macros n'ont pas changé de C. Puisque C n'a pas la surcharge et les arguments par défaut pour les fonctions, il n'a certainement pas pour les macros. Donc, pour répondre à votre question: non, ces caractéristiques n'existent pas pour les macros. Votre seule option est de définir plusieurs macros avec des noms différents (ou pas utiliser les macros).
Au passage: En C++, il est généralement considéré comme une bonne pratique pour se déplacer loin de macros autant que possible. Si vous avez besoin de fonctionnalités comme cela, il ya une bonne chance que vous êtes la surutilisation de macros.
Pour toute personne douloureusement à la recherche de quelques VA_NARGS solution qui fonctionne avec Visual C++. Macro suivante travaillé pour moi parfaitement(avec un zéro paramètres!) dans visual c++ express 2010:
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,N,...) N
#define VA_NUM_ARGS_IMPL_(tuple) VA_NUM_ARGS_IMPL tuple
#define VA_NARGS(...) bool(#__VA_ARGS__) ? (VA_NUM_ARGS_IMPL_((__VA_ARGS__, 24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1))) : 0
Si vous voulez une macro avec paramètres facultatifs que vous pouvez faire:
//macro selection(vc++)
#define SELMACRO_IMPL(_1,_2,_3, N,...) N
#define SELMACRO_IMPL_(tuple) SELMACRO_IMPL tuple
#define mymacro1(var1) var1
#define mymacro2(var1,var2) var2*var1
#define mymacro3(var1,var2,var3) var1*var2*var3
#define mymacro(...) SELMACRO_IMPL_((__VA_ARGS__, mymacro3(__VA_ARGS__), mymacro2(__VA_ARGS__), mymacro1(__VA_ARGS__)))
Cela a fonctionné pour moi aussi dans vc. Mais il ne fonctionne pas pour zéro des paramètres.
int x=99;
x=mymacro(2);//2
x=mymacro(2,2);//4
x=mymacro(2,2,2);//8
gcc
/g++
soutient les varargs macros mais je ne pense pas que c'est la norme, afin de l'utiliser à vos propres risques.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.