2011-12-21 19 views
8

के रूप में तर्क मेरे पास कई चर हैं जिन्हें इंजीनियरिंग विनिर्देश दस्तावेज़ में तत्वों के समान नाम दिया गया है, इसलिए नाम का स्ट्रिंग संस्करण भी उपयोगी है।सी/सी ++ मैक्रो तर्क के लिए विस्तार, स्ट्रिंग

#define MACRO(a) a, #a 

विशिष्ट उपयोग है:

void someFunction(int a, const char *name); 

someFunction(MACRO(meaningfully_named_variable)); 

मेरा प्रश्न तिगुना है:

  • वहाँ की एक बेहतर तरीका है

    मैं अपने आप को इस तरह एक बहुत मैक्रो का उपयोग लगता है यह कर रहा हूं?

  • बूस्ट या अन्य पुस्तकालयों में एक समान मैक्रो उपलब्ध है?
  • यदि नहीं, तो मैं इसे स्पष्ट और उपयोगी बनाने के लिए इसे कैसे परिष्कृत और पुनर्नामित कर सकता हूं?

संपादित मैंने कहा जाना चाहिए था कि इसके बाद के संस्करण एक न्यूनतम उदाहरण है। फ़ंक्शन में अन्य पैरामीटर हो सकते हैं और नामित इकाई डेटा सदस्य हो सकती है या शायद एक फ़ंक्शन भी हो सकती है।

सी ++ के लिए मैं एक और एक्सटेंशन पर विचार कर रहा हूं वह एक वर्ग NamedRef है जो मैक्रो की सामग्री प्राप्त कर सकता है।

template <typename T> 
struct NamedRef 
{ 
    NamedRef(T *t, const char *name) : t(t), name(name) { } 
    T *t; 
    const char *name; 
}; 

template <typename T> 
NamedRef<T> namedRef(T &t, const char *name) 
{ 
    return NamedRef<T>(&t, name); 
} 

#define WITH_NAME(a) a, #a 

// more sophisticated usage example 
void otherFunction(double, NamedRef<int>, bool); 

otherFunction(0.0, namedRef(object.WITH_NAME(meaningful_member_name)), false); 
+3

मै मैक्रो के लिए एक और वर्णनात्मक नाम चुनूंगा, उदाहरण के लिए 'WITH_NAME()'। –

+0

क्या करें @MarkRansom ने सुझाव दिया। मेरा जवाब "यह ठीक है" कहने का एक लंबा तरीका था और बूस्ट के पास 'BOOST_STRINGIZE (X)' नामक एक मैक्रो है। – AusCBloke

उत्तर

5

आप इसे आगे एक कदम ले सकता है:

#define SOMEFUNCTION(a) somefunction(a, #a) 

हालांकि, यह केवल उपयोगी है अगर आप एक ही समारोह बहुत कहते हैं। अन्यथा, मुझे नहीं लगता कि आपके उदाहरण से कोई बेहतर तरीका है। बेशक, आपको मैक्रो का नाम कुछ और अर्थपूर्ण में बदलना चाहिए, जैसे कि ARGUMENTS या कुछ।

+0

सच है, लेकिन अगर मेरे पास बहुत सारे फ़ंक्शन हैं जो 'var, name' प्राप्त करते हैं तो मुझे बहुत सारे मैक्रोज़ लिखना होगा। – paperjam

+0

जरूरी नहीं है => '# मैक्रो (funct_ptr, var) funct_ptr (var, #var)' परिभाषित करें तो आपको ऐसे कई मैक्रो की आवश्यकता होगी जो आपके पास फ़ंक्शन पैरामीटर के कितने अलग हस्ताक्षर हैं ... –

+0

ठीक है, अच्छी सोच है, लेकिन मुझे लगता है कि यदि संभव हो तो फ़ंक्शन सिंटैक्स को संरक्षित करना स्पष्ट है, फ़ंक्शन में अन्य तर्क भी हो सकते हैं। – paperjam

0
#define someFunction(a) if (1) stringized_someFunction((a), #a); else (void)0 
void stringized_someFunction(int a, const char* name); 

अगर (1) सामान मैक्रो ऊपर लपेटता इतना है कि यह गड़बड़ नहीं (आमतौर पर) के साथ छोरों, शाखाओं, अगर बयान, आदि

तब आप अपने समारोह इतना की तरह कहेंगे होगा:

int r = 4; 
someFunction(r); 

आप केवल वास्तव में एक अतिरिक्त लाइन प्रत्येक के लिए जोड़ें "समारोह घोषणा।" यदि सी प्रीप्रोसेसर ने कई चरणों की अनुमति दी है तो आप इसे सब एक में लपेट सकते हैं, लेकिन हां, यह नहीं है।

मैं भूल गया था क्योंकि मुझे आशा है कि यह स्पष्ट है कि आप अपने समारोह लिखने की ज़रूरत करेंगे:

void stringized_someFunction(int a, const char* name) 
{ 
    // Do stuff here 
} 

किसी भी तरह यह कि जिस तरह से पढ़ने के लिए बहुत आसान और खूबसूरत होना चाहिए।

+1

आप इससे पहले अपनी मैक्रो परिभाषा में अर्धविराम भूल गए हैं। इसके अलावा, मुझे लगता है कि अगर इस स्थिति में (1) आवश्यक है तो इसे लपेटना नहीं है। –

+0

@ जेसे धन्यवाद। लपेटना अगर (1) हमेशा जरूरी है। –

+1

मुझे पता है कि आपको [बहु-कथन मैक्रोज़ लपेटने की आवश्यकता है] (http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Multi-statement_Macro) उन्हें कोड तोड़ने से रोकने के लिए, लेकिन मुझे समझ में नहीं आता एकल बयान का कारण, यदि आप एक प्रति उदाहरण प्रदान कर सकते हैं तो इसकी सराहना की जाएगी। –

0

आपको लगता है कि XMACRO एस इस तरह के काम के लिए उपयोगी हैं।

0

के रूप में जेसी ने उत्तर दिया,

आप इस तरह लिख सकते हैं:

void function1(int a, const char* name) 
{ 
    cout << "a: " << a << endl; 
    cout << "name: " << name << endl; 
} 

void function2(double d, const char* name, const char *str) 
{ 
    cout << "d: " << d << endl; 
    cout << "name: " << name << endl; 
    cout << "str: " << str << endl; 
} 

#define MACRO(functionName, a) functionName(a, #a) 
#define MACRO2(functionName, a, ...) functionName(a, #a, __VA_ARGS__) 

int main() 
{ 
    int a = 10; 
    MACRO(function1, a); 
    double d = 10.5; 
    MACRO2(function2, d, "Hello world"); 
    return 0; 
} 

आप और अधिक तर्क है पारित करने के लिए, आप MACRO2 चर तर्क का उपयोग करता है का उपयोग कर सकते हैं। आपको तदनुसार फ़ंक्शन नाम पारित करना होगा।

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