2011-06-29 4 views
6

निम्नलिखित कोड कोड है:कक्षा के लिए कॉन्स्ट संस्करण पर गैर-कॉन्स संस्करण क्यों चुना जाता है?

struct A 
{ 
    operator int(); 
    operator int() const; 
}; 

void foo (const int); 

अब, invoking पर:

foo(A()); // calls A::operator int() 

यह always chooses the non-const version क्यों है? Xzx21 को भी foo() का आह्वान करने पर कोई प्रभाव नहीं पड़ता है। मानक संदर्भ के अलावा, क्या कोई तर्कसंगत रूप से समझा सकता है, इसके पीछे कारण?

उत्तर

13

A() आपको अस्थायी A ऑब्जेक्ट देता है जो कि कॉन्स्ट-क्वालिटी नहीं है। A() अभिव्यक्ति एक रैल्यू अभिव्यक्ति है, हां, लेकिन यह A ऑब्जेक्ट कॉन्स्ट-योग्य नहीं बनाता है।

के बाद से A वस्तु स्थिरांक-योग्य नहीं है, गैर स्थिरांक operator int() एक सटीक मिलान और स्थिरांक operator int() की आवश्यकता है एक योग्यता रूपांतरण है, इसलिए गैर स्थिरांक अधिभार सबसे अच्छा मैच के रूप में चुना गया है।

आप इसे स्थिरांक-योग्य होने के लिए चाहते हैं, तो आप आवश्यकता होगी स्पष्ट रूप से अनुरोध करने के लिए एक स्थिरांक योग्य A:

foo(identity<const A>::type()); 

जहां identity रूप

template <typename T> 
struct identity { typedef T type; }; 

नोट परिभाषित किया गया है है कि वहाँ वास्तव में operator const int() const और operator int() const के बीच कोई अंतर नहीं: परिणाम एक रैवल्यू है और केवल क्लास-प्रकार के रावलों को कॉन्स्ट-क्वालिफाइड किया जा सकता है (int कक्षा प्रकार नहीं है)।

ध्यान दें कि आपके पास और void foo(int) के बीच कोई अंतर नहीं है। पैरामीटर प्रकारों पर शीर्ष-स्तरीय कॉन्स-क्वालीफायर फ़ंक्शन के प्रकार को प्रभावित नहीं करते हैं (यानी, उन दोनों घोषणाओं का प्रकार void foo(int) है)। अन्य कारणों से, ऐसा इसलिए है क्योंकि यह कॉलर से कोई फर्क नहीं पड़ता कि शीर्ष-स्तरीय कॉन्स्ट-क्वालीफायर है या नहीं; इसे परवाह किए बिना एक प्रतिलिपि बनाना है। शीर्ष-स्तरीय कॉन्स-क्वालीफायर केवल फ़ंक्शन की परिभाषा को प्रभावित करता है।

+0

यहां तक ​​कि 'A' एक सामान्य ढेर/ढेर आवंटित वस्तु (अस्थायी नहीं) किया जा रहा है, यह एक ही परिणाम देता है। – iammilind

+0

यदि ऑब्जेक्ट कॉन्स्टेबल नहीं है, तो गैर-कॉन्स अधिभार अधिभार रिज़ॉल्यूशन के दौरान एक बेहतर मिलान है। क्या कोई कारण है कि आप उम्मीद करेंगे कि यह मामला न हो? –

+0

मैं उलझन में क्यों हूं, भले ही 'foo() '' const int' प्राप्त करता है और हमारे पास 'ए :: ऑपरेटर कॉन्स int() const;' है, फिर भी यह सामान्य 'ए :: ऑपरेटर int' चुनता है और चुनता है । – iammilind

4

एक नियम आपको सी ++ के बारे में याद रखना होगा: यह कभी भी उस मान को ध्यान में रखता है जब यह अधिभार का चयन करता है। इस मामले में operator int फ़ंक्शन कोई पैरामीटर नहीं लेता है, इसलिए यह विकल्पों को कम करने के लिए पैरामीटर सूची का उपयोग नहीं कर सकता है। यह सब उस वस्तु की स्थिरता का उपयोग कर सकता है जिसे इसे से बुलाया जा रहा है। चूंकि यह एक नई अस्थायी वस्तु है, यह स्थिर नहीं है, इसलिए यह कॉन्स्ट अधिभार का चयन नहीं करता है।

+1

* कभी * शायद बहुत मजबूत नहीं है; अधिभार को हल करते समय रिटर्न प्रकार को ध्यान में रखा जाता है किसी फ़ंक्शन का पता लेते समय, और एक स्वचालित रूपांतरण के लिए रूपांतरण ऑपरेटरों को हल करते समय। (बाद में जब आप रिटर्न प्रकार पर फ़ंक्शन ओवरलोड करना चाहते हैं तो बाद में उपयोगी हो सकता है। क्या यह विभिन्न रूपांतरण ऑपरेटरों के साथ प्रॉक्सी लौटाता है।) –

5

James McNellis ’ उत्तर वास्तव में इसे सभी को कवर करता है, लेकिन यह ’ टी को अधिक स्पष्टीकरण के साथ चोट पहुंचता है (मुझे आशा है)।

तो।

जब आप कॉल करते हैं & hellip;

o.operator int() 

और नरकिप; तो अधिभार चयन पूरी तरह से पर o की स्थिरता पर निर्भर करता है।

कुछ और नहीं।

क्यों देखने के लिए, इस वर्ग पर विचार करें:

struct Bar 
{ 
    void f() {} 
    void f() const {} 
}; 

तकनीकी तौर पर उन सदस्य कार्यों सदस्य कार्यों होने की जरूरत नहीं है। वे मुफ्त खड़े कार्यों के लिए भी चुना जा सकता है। लेकिन तब वे Bar तर्क की जरूरत है:

struct Bar 
{}; 

void f(Bar&) {} 
void f(Bar const&) {} 

और उम्मीद है कि अब यह देखने के लिए कि जब आप

Bar o; 
f(o); 

करना तो पहले समारोह का चयन किया जा सकता है आसान है। और इसलिए यह है। क्योंकि यदि दूसरा फ़ंक्शन चुना गया था, तो आप पहले कभी नहीं प्राप्त कर सकते थे। क्योंकि यदि आप ऑब्जेक्ट const बनाते हैं, तो यह पहले को चुनने के लिए const शुद्धता को तोड़ देगा। तो जब ऑब्जेक्ट const केवल दूसरा चुना जा सकता है, इसलिए, जब यह const नहीं है तो पहला चयन किया जाता है।

संक्षेप में, इस नियम का एकमात्र व्यावहारिक विकल्प हमेशा दूसरे का चयन करना होगा, जो पहले व्यक्ति को बेकार बना देगा, हां?

चीयर्स & hth।,

+0

यदि गैर-कॉन्स संस्करण निजी बनाया गया है, तो यह अभी भी सार्वजनिक सदस्य संस्करण के बजाय उस का उपयोग करने का प्रयास करता है, जिसके परिणामस्वरूप "निजी सदस्य तक पहुंचने का प्रयास" त्रुटि हो रही है! गुस्सा कर देने वाला। – Oktalist

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