क्या सी ++ मैक्रोज़ के साथ वैकल्पिक पैरामीटर प्राप्त करने का कोई तरीका है? किसी तरह का ओवरलोडिंग भी अच्छा होगा।
No you can't
क्या सी ++ मैक्रोज़ के साथ वैकल्पिक पैरामीटर प्राप्त करने का कोई तरीका है? किसी तरह का ओवरलोडिंग भी अच्छा होगा।
No you can't
जवाबों:
यहाँ यह करने का एक तरीका है। यह दो बार तर्कों की सूची का उपयोग करता है, पहले हेल्पर मैक्रो का नाम बनाने के लिए, और फिर उस हेल्पर मैक्रो के लिए तर्कों को पास करने के लिए। यह एक मैक्रो को तर्कों की संख्या की गणना करने के लिए एक मानक चाल का उपयोग करता है।
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;
}
यह मैक्रो के कॉलर के लिए आसान बनाता है, लेकिन लेखक के लिए नहीं।
PRINT_STRING_MACRO_CHOOSER
भी जरूरत है? क्या मैं इसके आंतरिक शरीर को सीधे बदल सकता हूं और इस पूरी चीज को कॉल कर सकता हूं (__VA_ARGS__)
?
अपने जवाब के लिए डेरेक लेडबेटर के साथ बहुत सम्मान के साथ - और एक पुराने प्रश्न को पुनर्जीवित करने के लिए माफी के साथ।
यह क्या कर रहा था की समझ पाने के लिए और कहीं और से आगे बढ़ाने की क्षमता के __VA_ARGS__
साथ ##
मुझे एक बदलाव के साथ आने की अनुमति दी ...
// 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__)\
)
मेरे जैसे गैर-विशेषज्ञों के लिए, जो जवाब पर ठोकर खाते हैं, लेकिन यह देख नहीं सकते कि यह कैसे काम करता है, मैं वास्तविक प्रसंस्करण के माध्यम से कदम रखूंगा, जो निम्नलिखित कोड के साथ शुरू होता है ...
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
हो जाता है ...
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) );
जो सिर्फ छठा तर्क बन जाता है ...
XXX_0();
XXX_1(1);
XXX_2(1,2);
XXX_3(1,2,3);
XXX_4(1,2,3,4);
5;
पुनश्च: संकलन त्रुटि प्राप्त करने के लिए XXX_0 के लिए #define निकालें [अर्थात: यदि कोई तर्क-वितर्क विकल्प की अनुमति नहीं है]।
PPS: अमान्य स्थितियों के लिए अच्छा होगा (जैसे: 5) कुछ ऐसा हो जो प्रोग्रामर को एक स्पष्ट संकलन त्रुटि दे!
PPPS: मैं एक विशेषज्ञ नहीं हूं, इसलिए मुझे टिप्पणियाँ (अच्छी, बुरी या अन्य) सुनकर बहुत खुशी हो रही है!
XXX_X(,##__VA_ARGS__,` ...
XXX_X (,, XXX_4 (), XXX_3 (), XXX_2 (), XXX_1 (), XXX_0 ()); `
C ++ मैक्रोज़ C. से परिवर्तित नहीं हुआ है, क्योंकि C में फ़ंक्शंस के लिए ओवरलोडिंग और डिफ़ॉल्ट तर्क नहीं थे, यह निश्चित रूप से उन्हें मैक्रोज़ के लिए नहीं था। तो आपके सवाल का जवाब देने के लिए: नहीं, उन सुविधाओं में मैक्रोज़ मौजूद नहीं हैं। आपका एकमात्र विकल्प कई मैक्रोज़ को अलग-अलग नामों से परिभाषित करना है (या मैक्रोज़ का उपयोग न करें)।
एक विचार के रूप में: C ++ में आम तौर पर जितना संभव हो उतना मैक्रोज़ से दूर जाने के लिए अच्छा अभ्यास माना जाता है। यदि आपको इस तरह की सुविधाओं की आवश्यकता है, तो एक अच्छा मौका है जब आप मैक्रोज़ का उपयोग कर रहे हैं।
__FILE__
और चीजों के साथ __LINE__
... और
डेरेक लेडबेटेर , डेविड सोर्कोवस्की , अपने उत्तरों के लिए सिफरलेट के साथ सबसे बड़े सम्मान के साथ , जेन्स गुस्टेड द्वारा खाली मैक्रो तर्कों का पता लगाने के लिए सरल विधि के साथ। पर
https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
अंत में मैं एक ऐसी चीज के साथ बाहर आता हूं जिसमें सभी चालें शामिल हैं, ताकि समाधान हो
, ##__VA_ARGS__
GCC / CLANG के लिए विशिष्ट अभिव्यक्ति द्वारा निगल रहा अल्पविराम , और ##__VA_ARGS__
MSVC के लिए अंतर्निहित निगल )। तो बेझिझक गुज़रे ज़माने को याद करो--std=c99
यदि आप चाहें तो अपने संकलक को )उचित रूप से क्रॉस-प्लेटफ़ॉर्म पर काम करता है , कम से कम के लिए परीक्षण किया गया
Lazies के लिए, स्रोत की प्रतिलिपि बनाने के लिए बस इस पोस्ट के अंतिम पर जाएं। नीचे विस्तृत विवरण दिया गया है, जो सभी लोगों को __VA_ARGS__
मेरे जैसे सामान्य समाधानों की तलाश में मदद करता है। =)
यहाँ है कि यह कैसे जाता है। सबसे पहले उपयोगकर्ता के लिए दृश्यमान अतिभारित "समारोह" को परिभाषित, मैं इसे नाम दिया है create
, और संबंधित वास्तविक समारोह परिभाषा realCreate
, और तर्क के विभिन्न संख्या के साथ मैक्रो परिभाषाओं CREATE_2
, CREATE_1
, CREATE_0
, नीचे दिखाया गया है:
#define create(...) MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
void realCreate(int x, int y)
{
printf("(%d, %d)\n", x, y);
}
#define CREATE_2(x, y) realCreate(x, y)
#define CREATE_1(x) CREATE_2(x, 0)
#define CREATE_0() CREATE_1(0)
MACRO_CHOOSER(__VA_ARGS__)
भाग अंततः मैक्रो परिभाषा के नाम पर ले कर जाता है, और दूसरा (__VA_ARGS__)
हिस्सा उनके पैरामीटर सूचियों शामिल हैं। तो एक उपयोगकर्ता के कॉल को create(10)
हल करने के लिए CREATE_1(10)
, CREATE_1
भाग से आता है MACRO_CHOOSER(__VA_ARGS__)
, और (10)
भाग दूसरे से आता है(__VA_ARGS__)
।
MACRO_CHOOSER
ट्रिक का उपयोग करता है, यदि __VA_ARGS__
खाली है, तो निम्नलिखित अभिव्यक्ति को प्रीप्रोसेसर द्वारा वैध मैक्रो कॉल में समाहित किया गया है:
NO_ARG_EXPANDER __VA_ARGS__ () // simply shrinks to NO_ARG_EXPANDER()
स्वाभाविक रूप से, हम इस परिणामी मैक्रो कॉल को परिभाषित कर सकते हैं
#define NO_ARG_EXPANDER() ,,CREATE_0
दो अल्पविरामों पर ध्यान दें, उन्हें जल्द ही समझाया गया है। अगला उपयोगी मैक्रो है
#define MACRO_CHOOSER(...) CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER __VA_ARGS__ ())
इसलिए की कॉल
create();
create(10);
create(20, 20);
वास्तव में विस्तारित हैं
CHOOSE_FROM_ARG_COUNT(,,CREATE_0)();
CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER 10 ())(10);
CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER 20, 20 ())(20, 20);
जैसा कि मैक्रो नाम से पता चलता है, हम बाद में तर्कों की संख्या की गणना कर रहे हैं। यहां एक और चाल आती है: प्रीप्रोसेसर केवल सरल पाठ प्रतिस्थापन करता है। यह कोष्ठक के अंदर देखे जाने वाले कॉमा की संख्या से एक मैक्रो कॉल के तर्कों की संख्या को कम करता है। अल्पविराम द्वारा अलग किए गए वास्तविक "तर्कों" को वैध सिंटैक्स की आवश्यकता नहीं है। वे कोई भी पाठ हो सकते हैं। यह कहना है, उपरोक्त उदाहरण में, NO_ARG_EXPANDER 10 ()
मध्य कॉल के लिए 1 तर्क के रूप में गिना जाता है। NO_ARG_EXPANDER 20
तथा20 ()
क्रमशः नीचे कॉल के लिए 2 तर्क के रूप में गिना जाता है।
यदि हम आगे के विस्तार के लिए निम्नलिखित हेल्पर मैक्रोज़ का उपयोग करते हैं
##define CHOOSE_FROM_ARG_COUNT(...) \
FUNC_RECOMPOSER((__VA_ARGS__, CREATE_2, CREATE_1, ))
#define FUNC_RECOMPOSER(argsWithParentheses) \
FUNC_CHOOSER argsWithParentheses
GCC / CLANG के लिए काम के ,
बाद की अनुगामी CREATE_1
, एक (झूठी सकारात्मक) त्रुटि को दबाते हुए कह रही है किISO C99 requires rest arguments to be used
जब -pedantic
आपके कंपाइलर के पास जा रहे हों। FUNC_RECOMPOSER
MSVC के लिए एक काम के आसपास है, या इसे सही ढंग से मैक्रो कॉल की कोष्ठकों के अंदर तर्क की संख्या (यानी, अल्पविराम) गिनती नहीं कर सकते हैं। इसके परिणामों का और समाधान किया जाता है
FUNC_CHOOSER (,,CREATE_0, CREATE_2, CREATE_1, )();
FUNC_CHOOSER (NO_ARG_EXPANDER 10 (), CREATE_2, CREATE_1, )(10);
FUNC_CHOOSER (NO_ARG_EXPANDER 20, 20 (), CREATE_2, CREATE_1, )(20, 20);
जैसा कि ईगल-आइड, आपने देखा होगा, अंतिम आवश्यकता केवल एक कदम है जो एक मानक तर्क गिनती चाल को नियोजित करने के लिए है जो अंत में वांछित मैक्रो संस्करण के नाम को चुनना है:
#define FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3
जो परिणामों को हल करता है
CREATE_0();
CREATE_1(10);
CREATE_2(20, 20);
और निश्चित रूप से हमें वांछित, वास्तविक फ़ंक्शन कॉल देता है:
realCreate(0, 0);
realCreate(10, 10);
realCreate(20, 20);
सभी को एक साथ रखना, बेहतर पठनीयता के लिए बयानों के कुछ पुनर्व्यवस्था के साथ, 2-तर्क उदाहरण का पूरा स्रोत का यहां है:
#include <stdio.h>
void realCreate(int x, int y)
{
printf("(%d, %d)\n", x, y);
}
#define CREATE_2(x, y) realCreate(x, y)
#define CREATE_1(x) CREATE_2(x, 0)
#define CREATE_0() CREATE_1(0)
#define FUNC_CHOOSER(_f1, _f2, _f3, ...) _f3
#define FUNC_RECOMPOSER(argsWithParentheses) FUNC_CHOOSER argsWithParentheses
#define CHOOSE_FROM_ARG_COUNT(...) FUNC_RECOMPOSER((__VA_ARGS__, CREATE_2, CREATE_1, ))
#define NO_ARG_EXPANDER() ,,CREATE_0
#define MACRO_CHOOSER(...) CHOOSE_FROM_ARG_COUNT(NO_ARG_EXPANDER __VA_ARGS__ ())
#define create(...) MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
int main()
{
create();
create(10);
create(20, 20);
//create(30, 30, 30); // Compilation error
return 0;
}
हालांकि, जटिल, बदसूरत, एपीआई डेवलपर पर बोझ डालते हुए, हमें पागल लोगों के लिए C / C ++ फ़ंक्शन के वैकल्पिक मापदंडों को ओवरलोड करने और स्थापित करने का एक समाधान आता है। आने वाले ओवरलोड एपीआई का उपयोग बहुत सुखद और सुखद हो जाता है। =)
यदि इस दृष्टिकोण का कोई और संभव सरलीकरण है, तो कृपया मुझे बताएं
https://github.com/jason-deng/C99FunctionOverload
फिर से सभी शानदार लोगों के लिए विशेष धन्यवाद जिन्होंने मुझे प्रेरित किया और मुझे इस काम को प्राप्त करने के लिए प्रेरित किया! =)
किसी को भी दर्द के लिए कुछ VA_NARGS समाधान की खोज जो Visual C ++ के साथ काम करता है। निम्नलिखित मैक्रो ने मेरे लिए दोषपूर्ण (शून्य मापदंडों के साथ भी) दृश्य c ++ एक्सप्रेस 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
यदि आप वैकल्पिक पैरामीटर के साथ एक मैक्रो चाहते हैं जो आप कर सकते हैं:
//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__)))
कि मेरे लिए vc में aswell काम किया। लेकिन यह शून्य मापदंडों के लिए काम नहीं करता है।
int x=99;
x=mymacro(2);//2
x=mymacro(2,2);//4
x=mymacro(2,2,2);//8
unresolved external symbol _bool referenced in function _main
gcc
/ varargs macrosg++
का समर्थन करता है, लेकिन मुझे नहीं लगता कि यह मानक है, इसलिए इसे अपने जोखिम पर उपयोग करें।
#include <stdio.h>
#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, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,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
#define PP_CONCAT(a,b) PP_CONCAT_(a,b)
#define PP_CONCAT_(a,b) a ## b
#define THINK(...) PP_CONCAT(THINK_, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#define THINK_0() THINK_1("sector zz9 plural z alpha")
#define THINK_1(location) THINK_2(location, 42)
#define THINK_2(location,answer) THINK_3(location, answer, "deep thought")
#define THINK_3(location,answer,computer) \
printf ("The answer is %d. This was calculated by %s, and a computer to figure out what this"
" actually means will be build in %s\n", (answer), (computer), (location))
int
main (int argc, char *argv[])
{
THINK (); /* On compilers other than GCC you have to call with least one non-default argument */
}
अस्वीकरण: ज्यादातर हानिरहित।
:%s/MY_MACRO_/THINK_/g
:)
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
यह वास्तव में नहीं है जो प्रीप्रोसेसर के लिए डिज़ाइन किया गया है।
कहा कि, यदि आप पठनीयता के एक मोडिक के साथ गंभीरता से चुनौतीपूर्ण मैक्रो प्रोग्रामिंग के क्षेत्र में प्रवेश करना चाहते हैं, तो आपको बूस्ट प्रीप्रोसेसर लाइब्रेरी पर एक नज़र डालनी चाहिए । आखिरकार, यह C ++ नहीं होगा अगर प्रोग्रामिंग के तीन पूरी तरह से अनुकूल संगत स्तर (प्रीप्रोसेसर, टेम्पलेट मेटाप्रोग्रामिंग और बेस लेवल C ++) नहीं थे!
#define MY_MACRO_3(X,Y,Z) ...
#define MY_MACRO_2(X,Y) MY_MACRO(X,Y,5)
#define MY_MACRO_1(X) MY_MACRO(X,42,5)
आप कॉल के बिंदु पर जानते हैं कि आप कितने args पास करने जा रहे हैं ताकि वास्तव में ओवरलोडिंग की कोई आवश्यकता न हो।
डेरेक लेडबिटर कोड का अधिक संक्षिप्त संस्करण:
enum
{
plain = 0,
bold = 1,
italic = 2
};
void PrintString(const char* message = NULL, int size = 0, int style = 0)
{
}
#define PRINT_STRING(...) PrintString(__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;
}
भयानक मैक्रो राक्षसों के एक बड़े प्रशंसक के रूप में, मैं जेसन डेंग के जवाब पर विस्तार करना चाहता था और इसे वास्तव में प्रयोग करने योग्य बनाना था। (बेहतर या बदतर के लिए।) मूल का उपयोग करने के लिए बहुत अच्छा नहीं है क्योंकि आपको हर बार एक नया मैक्रो बनाने के लिए बड़े वर्णमाला सूप को संशोधित करने की आवश्यकता होती है और यदि आपको विभिन्न प्रकार के तर्कों की आवश्यकता होती है तो यह और भी बुरा है।
इसलिए मैंने इन सुविधाओं के साथ एक संस्करण बनाया:
वर्तमान में मैंने सिर्फ 16 तर्क दिए हैं, लेकिन अगर आपको अधिक (वास्तव में अभी की जरूरत है? आप बस मूर्खतापूर्ण हो रहे हैं ...) आप FUNC_CHOOSER और CHOOSE_FROM_ARG_COUNT को संपादित कर सकते हैं, तो NOARG_EXPANDER में कुछ अल्पविराम जोड़ें।
कृपया कार्यान्वयन पर अधिक जानकारी के लिए जेसन देंग का उत्कृष्ट उत्तर देखें, लेकिन मैं यहां सिर्फ कोड डालूंगा:
#include <stdio.h>
void realCreate(int x, int y)
{
printf("(%d, %d)\n", x, y);
}
// This part you put in some library header:
#define FUNC_CHOOSER(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, ...) _f16
#define FUNC_RECOMPOSER(argsWithParentheses) FUNC_CHOOSER argsWithParentheses
#define CHOOSE_FROM_ARG_COUNT(F, ...) FUNC_RECOMPOSER((__VA_ARGS__, \
F##_16, F##_15, F##_14, F##_13, F##_12, F##_11, F##_10, F##_9, F##_8,\
F##_7, F##_6, F##_5, F##_4, F##_3, F##_2, F##_1, ))
#define NO_ARG_EXPANDER(FUNC) ,,,,,,,,,,,,,,,,FUNC ## _0
#define MACRO_CHOOSER(FUNC, ...) CHOOSE_FROM_ARG_COUNT(FUNC, NO_ARG_EXPANDER __VA_ARGS__ (FUNC))
#define MULTI_MACRO(FUNC, ...) MACRO_CHOOSER(FUNC, __VA_ARGS__)(__VA_ARGS__)
// When you need to make a macro with default arguments, use this:
#define create(...) MULTI_MACRO(CREATE, __VA_ARGS__)
#define CREATE_0() CREATE_1(0)
#define CREATE_1(x) CREATE_2(x, 0)
#define CREATE_2(x, y) \
do { \
/* put whatever code you want in the last macro */ \
realCreate(x, y); \
} while(0)
int main()
{
create();
create(10);
create(20, 20);
//create(30, 30, 30); // Compilation error
return 0;
}
आप BOOST_PP_OVERLOAD
एक boost
पुस्तकालय से उपयोग कर सकते हैं ।
आधिकारिक बूस्ट डॉक से उदाहरण :
#include <boost/preprocessor/facilities/overload.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#define MACRO_1(number) MACRO_2(number,10)
#define MACRO_2(number1,number2) BOOST_PP_ADD(number1,number2)
#if !BOOST_PP_VARIADICS_MSVC
#define MACRO_ADD_NUMBERS(...) BOOST_PP_OVERLOAD(MACRO_,__VA_ARGS__)(__VA_ARGS__)
#else
// or for Visual C++
#define MACRO_ADD_NUMBERS(...) \
BOOST_PP_CAT(BOOST_PP_OVERLOAD(MACRO_,__VA_ARGS__)(__VA_ARGS__),BOOST_PP_EMPTY())
#endif
MACRO_ADD_NUMBERS(5) // output is 15
MACRO_ADD_NUMBERS(3,6) // output is 9
आपको जो चाहिए, उसके आधार पर, आप इसे मैक्रोज़ के साथ var args के साथ कर सकते हैं। अब, वैकल्पिक पैरामीटर या मैक्रो ओवरलोडिंग, ऐसी कोई बात नहीं है।
उपरोक्त उदाहरणों में से कोई भी (डेरेक लेडबेटेर, डेविड सोरकोवस्की और जो डी से) मैक्रों के साथ तर्क गिनने के लिए मेरे लिए माइक्रोसॉफ्ट वीसीसी 10 का उपयोग करके काम किया गया। इस __VA_ARGS__
तर्क को हमेशा एक ही तर्क के रूप में माना जाता है (टोकन-इसे साथ लेना ##
या नहीं), इसलिए वह तर्क शिफ्टिंग जिसमें उन उदाहरणों पर भरोसा किया जाता है वह काम नहीं करता है।
इसलिए, संक्षिप्त उत्तर, जैसा कि ऊपर कई अन्य लोगों द्वारा कहा गया है: नहीं, आप मैक्रोज़ को अधिभार नहीं दे सकते हैं या उन पर वैकल्पिक तर्क का उपयोग नहीं कर सकते हैं।