2013-10-18 7 views
8

मैं अपने तर्कों के माध्यम से इस post लूपिंग से मैक्रोज का उपयोग कर रहा हूं। सब कुछ अच्छा काम करता है! हालांकि, क्या इन दो CCB_CREATE और CCB_CREATE_MORE को गठबंधन करने का कोई तरीका है?सी ++ प्रीप्रोसेसर मैक्रो लूप __VA_ARGS__ 1 बनाम 2+ तर्क

मुझे अतिरिक्त कोड लिखने के लिए पहले तर्क object_type निकालने की आवश्यकता है। अतिरिक्त object_type एस मानचित्र में डालने के लिए FOR_EACH लूप का उपयोग करेगा।

संकलक शिकायतें जब CCB_CREATE_MORE(Type1) का उपयोग करते समय मेरे पास केवल एक तर्क होता है। इसे ठीक करने के लिए मैंने CCB_CREATE(Type1) को संभालने के लिए एक और मैक्रो बनाया। इन दोनों को एक सुरुचिपूर्ण मैक्रो में गठबंधन करने के लिए एक चालाक समाधान खोजने की उम्मीद है। कोई विचार?

#define INSERT_LOADER_MAP(object_type) loader_map.insert(make_pair(#object_type, object_type##Loader::loader())) 


#define CCB_CREATE_MORE(object_type,...) \ 
static CCNode * create##object_type##Node() { \ 
    std::map<std::string, CCNodeLoader*> loader_map; \ 
    std::string classname = #object_type; \ 
    FOR_EACH(INSERT_LOADER_MAP,object_type,__VA_ARGS__); \ 
    return loadCCBFile((classname + ".ccbi").c_str(), loader_map); \ 
} 


#define CCB_CREATE(object_type) \ 
static CCNode * create##object_type##Node() { \ 
    std::map<std::string, CCNodeLoader*> loader_map; \ 
    std::string classname = #object_type; \ 
    INSERT_LOADER_MAP(object_type); \ 
    return loadCCBFile((classname + ".ccbi").c_str(), loader_map); \ 
} 
+5

मैं '__type__' का उपयोग करने की अनुशंसा नहीं करता हूं। यह एक आरक्षित पहचानकर्ता है। – chris

+0

इसे इंगित करने के लिए धन्यवाद। बस एक खोज किया और उस पर प्रतिस्थापित किया। – docchang

उत्तर

5

संकलक संभावित रूप से पिछली कॉमा के बारे में शिकायत कर रहा है जब विविध तर्क सूची खाली है। जीसीसी और विजुअल स्टूडियो compilers अमानक विस्तार ##__VA_ARGS__ समर्थन अनुगामी अल्पविराम को दबाने के लिए:

#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__) 

दृश्य स्टूडियो compilers भी अनुगामी को दबाने होगा अल्पविराम भी ## विस्तार के बिना।

जीसीसी दस्तावेज here, और विजुअल स्टूडियो प्रलेखन here देखें।

यदि आपको मानकों-अनुरूप समाधान की आवश्यकता है, तो this question के उत्तर में एक विस्तृत विवरण दिया गया है।

तो अगर आप या तो जीसीसी या दृश्य स्टूडियो का उपयोग कर रहे हैं, तो आप इस सरल परिवर्तन के साथ अपने मूल मैक्रो का उपयोग करने में सक्षम होना चाहिए:

#define CCB_CREATE(object_type,...) \ 
static CCNode * create##object_type##Node() { \ 
    std::map<std::string, CCNodeLoader*> loader_map; \ 
    std::string classname = #object_type; \ 
    FOR_EACH(INSERT_LOADER_MAP,object_type,##__VA_ARGS__); \ 
    return loadCCBFile((classname + ".ccbi").c_str(), loader_map); \ 
} 

संपादित करें: आप में ##__VA_ARGS__ एक्सटेंशन का उपयोग करने की आवश्यकता होगी FOR_EACH() मैक्रो भी, या यूगोरन द्वारा सुझाए गए अधिक सुरुचिपूर्ण संशोधन।

2

Chris Olsen's suggestion के अलावा, FOR_EACH मैक्रो को एक मामूली बदलाव की आवश्यकता है:

#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__) 

नतीजतन, FOR_EACH(X, a)X(a) (X(a); X(); के बजाय) हो जाएगा। यह एक खाली INSERT_LOADER_MAP आमंत्रण को समाप्त करता है।

संबंधित मुद्दे