2011-05-23 13 views
5

यह सवाल थोड़ा सा स्पष्टीकरण लेने जा रहा है, क्षमा करें। मैं कुछ सी ++ कोड को पार्स करने में डॉक्सिजन में एक निरीक्षण को ठीक कर रहा हूं और मैं असामान्य कोने के मामले में आया हूं जो डॉक्सिजन का खाता नहीं है। मेरे पास एक फिक्स है लेकिन मैं इसे और अधिक सामान्य बनाना चाहता हूं इसलिए मुझे कुछ स्पष्टीकरण की आवश्यकता है।सी ++ किस प्रकार पैरामीटर प्रकार का नाम पैरामीटर नाम के रूप में एक प्रकार के विनिर्देशक के समान हो सकता है?

डॉक्सिजन विफल होने के मामले को चित्रित करने के लिए मैं सिम्पसंस से जुड़े एक प्रदूषित उदाहरण को परिभाषित करने जा रहा हूं (क्योंकि यह इस प्रकार के प्रश्नों के लिए लोकप्रिय प्रतीत होता है)।

enum simpson { HOMER, MARGE, BART, LISA, MAGGIE }; 

अब हम (द सिम्पसंस वर्ग स्वाभाविक रूप से) एक विधि में enum मूल्य पास करना चाहते हैं कि इस तरह दिखता है:

const char* voicedBy(simpson simpson) 
{ 
    switch (simpson) { 
     case HOMER: 
      return "Dan Castellaneta"; 
     case MARGE: 
      return "Julie Kavner"; 
     case BART: 
      return "Nancy Cartwright"; 
     case LISA: 
      return "Yeardley Smith"; 
     case MAGGIE: 
      return "*suck* *suck*"; 
    } 
} 

दुर्भाग्य से यह एक का उत्पादन कहते हैं कि हम निम्नलिखित enum करते हैं कंपाइलर त्रुटि क्योंकि enum type 'simpson' को पैरामीटर नाम 'सिम्पसन' के समान होने की अनुमति नहीं है (जैसा कि, कहें, सी #)। लेकिन, सी ++ का इसका जवाब है। आपने enum कीवर्ड को इस प्रकार के नाम के सामने रखा है:

const char* voicedBy(enum simpson simpson) 

और कोड अब संकलित और चलाएगा। दुर्भाग्यवश डॉक्सिजन इस मामले के लिए जिम्मेदार नहीं है और इसलिए यह पैरामीटर प्रकार के साथ पैरामीटर प्रकार के रूप में संपूर्ण स्ट्रिंग "एनम सिम्पसन सिम्पसन" का इलाज करता है। मैं ऊपर की तरह एक enum के मामले में डॉक्सिजन को ठीक करने के लिए कुछ कोड के साथ आया हूँ।

मेरा सवाल यह है कि इस प्रकार की चाल किस प्रकार की वैध है? संरचना ?, संघ ?, typedef ?, दूसरों? और उस मामले के लिए, 'पैरामीटर नाम' अवधारणा के समान विधि वाले विधि पैरामीटर के लिए टाइप विनिर्देश का नाम है ताकि मैं इसके बारे में कुछ और जानकारी प्राप्त कर सकूं?

+0

अच्छा (अच्छा ... "मुझे यह नहीं पता था" में अच्छा लगा, लेकिन _nice_ नहीं) चाल। –

+1

कृपया मुझे क्षमा करें जबकि मुझे लगता है कि जो भी कोड लिखा है और उन्हें चेहरे पर क्लब करें: पी। –

+0

क्या कंपाइलर और संस्करण? उपरोक्त कोड नमूना को * विस्तृत प्रकार विनिर्देश * के लिए किसी भी आवश्यकता के बिना संकलित करना चाहिए। –

उत्तर

2

आप किस कंपाइलर और संस्करण का उपयोग कर रहे हैं?

void foo(simpson simpson) {} 

नहीं enum मौजूद है, वह यह है कि आप इस संदर्भ में एक सविस्तार प्रकार निर्दिष्टकर्ता उपयोग करने के लिए की जरूरत नहीं है, और यह जीसीसी 4.2 और 4.6 में पूरी तरह से संकलित करता है। समस्या यह है कि अंदर समारोह, तर्क नाम छुपाता * प्रकार है, और आप अंदर उस प्रकार के साथ एक नया चर घोषित करने के लिए है कि गुंजाइश आप सविस्तार प्रकार निर्दिष्टकर्ता की आवश्यकता होगी चाहते हैं, लेकिन अगर समारोह हस्ताक्षर में इसे बाएं से दाएं पार्स किया गया है, और इसका मतलब है कि पहले simpson enum है और उस समय कोई टकराव नहीं है। दूसरा simpson एक स्थानीय नाम प्रस्तुत करता है, और वहां से simpson पैरामीटर को संदर्भित करता है, न कि प्रकार।

void relationship(/*enum*/ simpson simpson, enum simpson other = HOMER); 
//     ^^^^ optional   ^^^^ required 
{ 
    enum simpson yet_another = simpson; 
// ^^^^ required    ^^^^^^^ first argument! 
} 

नाम छुपा यदि आप प्रकार आप चाहते हैं के रूप में एक ही नाम के साथ एक समारोह को परिभाषित भी हो सकता है के एक ही प्रकार:

void simpson(); 
void voicedBy(enum simpson s); 
//    ^^^^ required 

नोट typedef चीजें एक को बदलने कि यदि आप एक जोड़ने इस आखिरी मामले में थोड़ा सा: टाइपिफ़-एड नाम और फ़ंक्शन नाम (या एक ही दायरे में एक चर नाम) के बीच एक नाम संघर्ष होगा।

* यहाँ छुपाता एक बाहरी दायरे में ही नाम के साथ एक चर छुपा एक दायरे में एक चर के अर्थ में नहीं किया जाता है। सी ++ में, सी में, दो पहचानकर्ता रिक्त स्थान हैं, एक उपयोगकर्ता परिभाषित प्रकारों के लिए, और दूसरा अन्य सभी चीज़ों के लिए typedef -ed प्रकार उपनाम शामिल हैं। सी ++ में लुकअप आंतरिक दायरे से बाहरी दायरे में किया जाता है, और प्रत्येक दायरे में वैश्विक पहचानकर्ता स्थान खोजा जाता है, यदि पहचानकर्ता नहीं मिला है, तो उपयोगकर्ता परिभाषित प्रकार पहचानकर्ता स्थान उसी पहचानकर्ता के लिए खोजा जाता है। यह अंतिम चरण सी में नहीं किया जाता है, जहां विस्तृत प्रकार विनिर्देशकों की हमेशा आवश्यकता होती है। केवल अगर वह भी विफल रहता है, तो संकलक अगले दायरे में चलेगा।

+0

जीसीसी 2.95.3। अंत में इसका परीक्षण किया गया और आप सही हैं, सी ++ कोड में विधि पैरामीटर के लिए enum भाग की आवश्यकता नहीं है, लेकिन उस प्रकार के स्थानीय चर घोषित करने के लिए आवश्यक है। मैंने यह जांच नहीं की कि नियमित कार्य के पैरामीटर के लिए enum की आवश्यकता है क्योंकि मैं उनका उपयोग नहीं करता हूं। –

1

struct/class/union भी। मानक में, "विस्तृत-प्रकार-विनिर्देशक", जिसमें "क्लास-कुंजी पहचानकर्ता" शामिल है, 3.4.4-1 देखें।

struct Point { 
    int x, y; 
}; 

enum Type { 
    FIRST, SECOND, THIRD 
}; 

struct Point p; 
enum Type t; 

कौन सा है: - (। BTW अगर एक switchcasereturn रों, यह break करने की कोई जरूरत नहीं है)

+0

मुझे पता था कि मैं अपने उदाहरण कोड में कुछ खराब कर दूंगा क्योंकि मैंने इसे संकलित नहीं किया था। –

+0

@ जॉन: :-)। यहां तक ​​कि वह इसे पकड़ा नहीं होगा - जैसा कि है, संकलित और ठीक काम करेगा ... केवल उन 'ब्रेक' लाइनों को निष्पादन के दौरान कभी नहीं पहुंचाया जा सकता है - वैसे भी ऑप्टिमाइज़र द्वारा हटाया जाना चाहिए, लेकिन कोड बिना बेहतर पढ़ेगा। –

3

सी में, एक struct, union का प्रामाणिक नाम, या enum उपसर्ग है जिसमें शामिल हैं उपसर्ग हटाया के साथ एक typedef नाम बनाने के मुहावरे के स्रोत के रूप में अच्छी तरह से

typedef struct Point { 
    int x, y; 
} Point; 

typedef enum Type { 
    FIRST, SECOND, THIRD 
} Type; 

struct Point p; 
enum Type t; 
Point p; 
Type t; 

सी ++ इस है, एक ही behaviou साथ आर class को भी दिया गया है, और टेम्पलेट्स में template और typename को समान व्यवहार दिया गया है। हालांकि, यह संदिग्ध मामलों को छोड़कर उपसर्ग सहित आवश्यकता को भी हटा देता है।

मुझे नहीं लगता था कि इस अवधारणा का नाम था, लेकिन मैं सही कहता हूं: यह विस्तृत प्रकार विनिर्देश है। इसके लिए एक उपयुक्त कामकाज परिभाषा के बजाय घोषणा पर Doxygen टिप्पणियां रखने के लिए हो सकता है।

+0

आपका उत्तर अच्छा है। टोनी को केवल यह जानने के लिए स्वीकार्य उत्तर मिला कि इसे 'विस्तृत प्रकार विनिर्देशक' कहा जाता है। –

1

आपने जो किया वह वही है जो सी कोडर पूरे दिन करते हैं - उचित उपयोगकर्ता के साथ अपने उपयोगकर्ता परिभाषित प्रकारों को उपसर्ग करते हैं। स्ट्रिप, कक्षा, यूनियन, टाइपिफ़ में, वैरिएबल घोषणाओं, मूल रूप से कहीं भी समान कार्य करता है।

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