সি ++ ম্যাক্রোসের সাথে alচ্ছিক পরামিতি পাওয়ার কোনও উপায় আছে কি? একরকম ওভারলোডিং খুব ভাল হবে।
No you can't
সি ++ ম্যাক্রোসের সাথে alচ্ছিক পরামিতি পাওয়ার কোনও উপায় আছে কি? একরকম ওভারলোডিং খুব ভাল হবে।
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__)
?
তার উত্তরের জন্য ডেরেক লেডবেটারের প্রতি অত্যন্ত শ্রদ্ধার সাথে - এবং একটি পুরানো প্রশ্ন পুনরুদ্ধারের জন্য ক্ষমাপ্রার্থী।
এটা কি করছেন এবং preceed করার ক্ষমতা অন্য কোথাও গোছগাছ একটি বোঝার পথ __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;
PS: একটি সংকলন ত্রুটি পেতে XXX_0 এর জন্য # ডেফাইনটি সরান [উদাহরণস্বরূপ: যদি কোনও নো-আর্গুমেন্ট বিকল্প অনুমোদিত না হয়]।
পিপিএস: অবৈধ পরিস্থিতিগুলি (যেমন: 5) এমন কিছু হতে পারে যা প্রোগ্রামারকে আরও পরিষ্কার সংকলন ত্রুটি দেয়!
পিপিপিএস: আমি বিশেষজ্ঞ নই, তাই মন্তব্য শুনে ভাল লাগল (ভাল, খারাপ বা অন্য)!
XXX_X(,##__VA_ARGS__,` ...
XXX_X (অন্যান্য XXX_4 (), XXX_3 এ (), XXX_2 এ (), XXX_1 আপনাকে (), XXX_0 ()); `
সি ++ ম্যাক্রোগুলি সি থেকে পরিবর্তিত হয়নি যেহেতু সি এর ক্রিয়াকলাপগুলির জন্য ওভারলোডিং এবং ডিফল্ট আর্গুমেন্ট নেই, এটি অবশ্যই ম্যাক্রোগুলির জন্য তাদের নেই। সুতরাং আপনার প্রশ্নের উত্তর দিতে: না, ম্যাক্রোগুলির জন্য এই বৈশিষ্ট্যগুলি বিদ্যমান নেই। আপনার একমাত্র বিকল্প হ'ল একাধিক ম্যাক্রোকে বিভিন্ন নামের সাথে সংজ্ঞায়িত করা (বা ম্যাক্রো মোটেই ব্যবহার করবেন না)।
সাইডেনোট হিসাবে: সি ++ এ সাধারণত ম্যাক্রো থেকে যতটা সম্ভব দূরে সরিয়ে নেওয়া ভাল অভ্যাস হিসাবে বিবেচিত হয়। আপনার যদি এর মতো বৈশিষ্ট্যগুলির প্রয়োজন হয় তবে আপনি ম্যাক্রোকে অতিরিক্ত ব্যবহার করছেন এমন একটি ভাল সুযোগ রয়েছে।
__FILE__
এবং এই জাতীয় জিনিসগুলির সাথে কিছুটা সহজ হয়ে যায় __LINE__
...
সবচেয়ে বড় সম্মান সঙ্গে ডেরেক Ledbetter, , ডেভিড Sorkovsky , Syphorlate তাদের উত্তরের জন্য, একসঙ্গে খালি ম্যাক্রো আর্গুমেন্ট সনাক্ত করতে প্রতিভাশালী পদ্ধতি সঙ্গে জেনস Gustedt এ
https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
অবশেষে আমি এমন কিছু নিয়ে আসলাম যা সমস্ত কৌশলকে সংযুক্ত করে, যাতে সমাধান
, ##__VA_ARGS__
জিসিসি / সিএলএং- এর নির্দিষ্ট অভিব্যক্তি দ্বারা কমা গিলে ফেলা, এবং ##__VA_ARGS__
এমএসভিসির জন্য নিখুঁত গিলে )। সুতরাং নিখরচায় --std=c99
আপনার কম্পাইলারের কাছে যদি আপনি চান =) পাস করুনযুক্তিসঙ্গতভাবে ক্রস প্ল্যাটফর্ম কাজ করে , কমপক্ষে এর জন্য পরীক্ষিত
অলসদের জন্য, উত্স অনুলিপি করতে কেবল এই পোস্টের একেবারে শেষ দিকে যান। নীচে বিস্তারিত ব্যাখ্যা দেওয়া হল, যা আশা করি __VA_ARGS__
আমার মতো সাধারণ সমাধানগুলির সন্ধানকারী সমস্ত লোককে সহায়তা এবং অনুপ্রেরণা যোগাবে । =)
এটি কিভাবে যায় তা এখানে। প্রথম ব্যবহারকারী দৃশ্যমান ওভারলোড "ফাংশন" define, আমি এটা নামে 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()
Ingeniusly, আমরা এই ফলস্বরূপ ম্যাক্রো কল হিসাবে সংজ্ঞায়িত করতে পারি
#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
চিহ্ন ,
পর 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);
আপনি যেমন agগল চোখের সাথে দেখে থাকতে পারেন, আমাদের কেবলমাত্র শেষ পদক্ষেপটি হ'ল ম্যাক্রো সংস্করণের নামগুলি বেছে নেওয়ার জন্য একটি স্ট্যান্ডার্ড আর্গুমেন্ট কাউন্টিং ট্রিক নিয়োগ করা:
#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;
}
যদিও জটিল, কুৎসিত, এপিআই বিকাশকারীকে বোঝা করা হচ্ছে, আমাদের পাগল লোকদের কাছে সি / সি ++ ফাংশনগুলির ওভারলোডিং এবং settingচ্ছিক পরামিতিগুলি সেট করার জন্য একটি সমাধান আসে। আগত ওভারলোড হওয়া এপিআইগুলির ব্যবহার খুব উপভোগ্য এবং মনোরম হয়ে ওঠে। =)
যদি এই পদ্ধতির আরও সম্ভাব্য সরলীকরণ হয় তবে দয়া করে আমাকে জানান
https://github.com/jason-deng/C99FunctionOverload
আবার উজ্জ্বল সকলকেই বিশেষ ধন্যবাদ যা আমাকে এই টুকরোটি কাজের জন্য অনুপ্রাণিত করেছে এবং পরিচালিত করেছে! =)
যার জন্য ভিজ্যুয়াল সি ++ এর সাথে কাজ করে এমন কিছু ভিএ_এনআরজিএস সমাধান বেদনাদায়কভাবে অনুসন্ধান করছে searching নিম্নলিখিত ম্যাক্রো ভিজ্যুয়াল সি ++ এক্সপ্রেস 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
আপনি যদি alচ্ছিক পরামিতি সহ ম্যাক্রো চান তবে আপনি এটি করতে পারেন:
//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__)))
এটি আমার পক্ষে উপাচার্যের পাশাপাশি কাজ করেছিল। তবে এটি শূন্য পরামিতিগুলির জন্য কাজ করে না।
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
/ ভারারাগ্স ম্যাক্রোগুলিকেg++
সমর্থন করে তবে আমি এটি মানক বলে মনে করি না, সুতরাং এটি আপনার নিজের ঝুঁকিতে ব্যবহার করুন।
#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)
এটি প্রিপ্রোসেসরটির জন্য ডিজাইন করা আসলেই নয়।
এটি বলেছে, আপনি যদি পঠনযোগ্যতার একটি মডিকাম সহ গুরুতরভাবে চ্যালেঞ্জিং ম্যাক্রো প্রোগ্রামিংয়ের ক্ষেত্রে প্রবেশ করতে চান তবে আপনার বুস্ট প্রিপ্রসেসর লাইব্রেরিটি একবার দেখে নেওয়া উচিত । সর্বোপরি, তিনটি সম্পূর্ণরূপে প্রোগ্রামিংয়ের টিউরিং সামঞ্জস্যপূর্ণ স্তর (প্রিপ্রোসেসর, টেমপ্লেট মেটাপ্রোগ্র্যামিং এবং বেস স্তর সি ++) না থাকলে এটি সি ++ হত না!
#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)
আপনি কল করতে পারেন যে আপনি কয়টি আরগ পাস করতে যাচ্ছেন তাই ওভারলোডিংয়ের সত্যিই দরকার নেই।
ডেরেক লেডবেটারের কোডের আরও সংক্ষিপ্ত সংস্করণ:
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;
}
ভয়াবহ ম্যাক্রো দানবগুলির একটি বড় অনুরাগী হিসাবে, আমি জেসন দেং এর উত্তরে প্রসারিত করে এটিকে আসলে ব্যবহারযোগ্য করে তুলতে চাইছিলাম। (আরও ভাল বা খারাপের জন্য)) আসলটি ব্যবহার করা খুব ভাল নয় কারণ আপনি প্রতিবার নতুন ম্যাক্রো তৈরি করতে চাইলে আপনাকে বড় বর্ণমালার স্যুপটি পরিবর্তন করতে হবে এবং আপনার যদি বিভিন্ন পরিমাণ যুক্তি যুক্ত করার প্রয়োজন হয় তবে এটি আরও খারাপ।
তাই আমি এই বৈশিষ্ট্যগুলি সহ একটি সংস্করণ তৈরি করেছি:
বর্তমানে আমি সর্বাধিক ১ argument টি আর্গুমেন্ট তৈরি করেছি, তবে যদি আপনার আরও প্রয়োজন হয় (সত্যিই এখন? আপনি কেবল নির্বোধ হয়ে যাচ্ছেন ...) আপনি FUNC_CHOOSER এবং CHOOSE_FROM_ARG_COUNT টি সম্পাদনা করতে পারেন, তারপরে NO_ARG_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
আপনার যা প্রয়োজন তার উপর নির্ভর করে আপনি ম্যাক্রো সহ ভেরিআরগগুলি দিয়ে এটি করতে পারেন । এখন, alচ্ছিক পরামিতি বা ম্যাক্রো ওভারলোডিং, এমন কোনও জিনিস নেই।
ম্যাক্রোসের সাথে যুক্তি গণনা করার জন্য উপরের উদাহরণগুলির মধ্যে (ডেরেক লেডবেটার, ডেভিড সারকোভস্কি এবং জো ডি থেকে) মাইক্রোসফ্ট ভিসিসি 10 ব্যবহার করে আমার পক্ষে কাজ __VA_ARGS__
করেছিল।##
বা না হোক), তাই যুক্তি স্থানান্তর যে ক্ষেত্রে উদাহরণগুলি নির্ভর করে কাজ করে না।
সুতরাং, সংক্ষিপ্ত উত্তর, যেমন উপরের আরও অনেকে বলেছেন: না, আপনি ম্যাক্রোগুলি ওভারলোড করতে পারবেন না বা তাদের উপর optionচ্ছিক যুক্তি ব্যবহার করতে পারবেন না।