कम
रूपांतरण फ़ंक्शन operator int()
का चयन क्लैंग ओवर द्वारा किया गया है operator bool() const
क्योंकि b
कांस्ट योग्य नहीं है, जबकि बूल के लिए रूपांतरण ऑपरेटर है।
संक्षिप्त तर्क यह है कि उम्मीदवार ओवरलोड रिज़ॉल्यूशन के लिए कार्य करते हैं (स्थान में निहित वस्तु पैरामीटर के साथ), जब इसे परिवर्तित b
किया bool
जा रहा है
operator bool (B2 const &);
operator int (B2 &);
जहां दूसरा एक बेहतर मैच है क्योंकि b
कांस्ट क्वालिफाइड नहीं है।
यदि दोनों फ़ंक्शन समान योग्यता साझा करते हैं (दोनों const
या तो नहीं), तो operator bool
इसका चयन किया जाता है क्योंकि यह प्रत्यक्ष रूपांतरण प्रदान करता है।
कास्ट-नोटेशन के माध्यम से रूपांतरण, कदम से कदम का विश्लेषण किया
अगर हम सहमत हैं कि बूलियन ostream Inserter (std :: basic_ostream :: ऑपरेटर << (bool वैल) [ostream.inserters.arithmetic] के अनुसार) मूल्य के साथ कहा जाता है इस बात का एक रूपांतरण से परिणाम b
के लिए bool
हम उस रूपांतरण में खुदाई कर सकते हैं ।
1. कलाकारों की अभिव्यक्ति
B से बूल की डाली
(bool)b
का मूल्यांकन करता है
static_cast<bool>(b)
के अनुसार सी ++ 11, 5.4 / 4 [expr.cast] के बाद से const_cast
(नहीं जोड़ने या यहाँ स्थिरांक को हटाने) लागू नहीं है।
यह स्थिर रूपांतरण प्रति C ++ 11, 5.2.9 / 4 [expr.static.cast] की अनुमति है , अगर bool t(b);
एक आविष्कार किया गया चर टी अच्छी तरह से बनता है। इस तरह के बयानों को C - 11, 8.5 / 15 [dcl.init] के अनुसार प्रत्यक्ष-आरंभ कहा जाता है ।
2. प्रत्यक्ष आरंभीकरण bool t(b);
सबसे कम उल्लिखित मानक पैराग्राफ राज्यों के खंड 16 (जोर मेरा):
आरम्भिकों के शब्दार्थ इस प्रकार हैं। डेस्टिनेशन टाइप, ऑब्जेक्ट या रेफरेंस को इनिशियलाइज़ किए जाने का प्रकार होता है और सोर्स टाइप इनिशियलाइज़र एक्सप्रेशन का प्रकार होता है।
[...]
[...] यदि स्रोत प्रकार एक (संभवतः cv-योग्य) वर्ग प्रकार है, तो रूपांतरण कार्यों पर विचार किया जाता है।
लागू रूपांतरण कार्यों की गणना की जाती है, और सबसे अच्छा एक अधिभार संकल्प के माध्यम से चुना जाता है।
2.1 कौन से रूपांतरण कार्य उपलब्ध हैं?
उपलब्ध रूपांतरण फ़ंक्शन हैं operator int ()
और operator bool() const
चूंकि C ++ 11, 12.3 / 5 [class.conv] हमें बताता है:
एक व्युत्पन्न वर्ग में एक रूपांतरण फ़ंक्शन एक बेस क्लास में रूपांतरण फ़ंक्शन को नहीं छुपाता है जब तक कि दो फ़ंक्शन एक ही प्रकार में परिवर्तित नहीं होते हैं।
जबकि C ++ 11, 13.3.1.5/1 [over.match.conv] बताता है:
एस और उसके आधार वर्गों के रूपांतरण कार्यों पर विचार किया जाता है।
जहाँ S वह वर्ग है जहाँ से परिवर्तित किया जाएगा।
2.2 कौन से रूपांतरण कार्य लागू हैं?
C ++ 11, 13.3.1.5/1 [over.match.conv] (जोर मेरा):
1 [...] यह मानते हुए कि "cv1 T" ऑब्जेक्ट के प्रकार को इनिशियलाइज़ किया जा रहा है, और "cv S" इनिशियललाइज़र एक्सप्रेशन का प्रकार है, S के साथ एक वर्ग प्रकार, उम्मीदवार फ़ंक्शंस निम्नानुसार चुने जाते हैं: रूपांतरण एस और इसके आधार वर्गों के कार्यों पर विचार किया जाता है। वे गैर-स्पष्ट रूपांतरण फ़ंक्शंस जो S और उपज प्रकार T के भीतर छिपे नहीं हैं या एक मानक रूपांतरण अनुक्रम के माध्यम से T टाइप करने के लिए परिवर्तित किया जा सकता है उम्मीदवार कार्य हैं।
इसलिए operator bool () const
लागू है क्योंकि यह भीतर छिपा नहीं है B2
और पैदावार करता है a bool
।
अंतिम मानक उद्धरण में जोर देने वाला भाग operator int ()
चूंकि रूपांतरण का उपयोग करने के लिए प्रासंगिक int
है, एक प्रकार है जिसे मानक रूपांतरण अनुक्रम के माध्यम से बूल में परिवर्तित किया जा सकता है। से रूपांतरण int
करने के लिए bool
भी नहीं एक दृश्य लेकिन एक सादे प्रत्यक्ष रूपांतरण जो प्रति अनुमति दी है है सी ++ 11, 4.12 / 1 [conv.bool]
अंकगणित, अनकैप्ड एन्यूमरेशन, पॉइंटर या पॉइंटर टू मेंबर टाइप के प्रील्यूव को टाइप बूल के प्रीलव्यू में बदला जा सकता है। शून्य मान, अशक्त सूचक मान या अशक्त सदस्य सूचक मान मिथ्या में परिवर्तित हो जाता है; किसी अन्य मान को सत्य में परिवर्तित किया जाता है।
इसका मतलब है कि operator int ()
यह लागू है।
2.3 किस रूपांतरण समारोह का चयन किया जाता है?
ओवरलोड रेजोल्यूशन ( C ++ 11, 13.3.1.5/1 [over.match.conf] ) के माध्यम से उपयुक्त रूपांतरण फ़ंक्शन का चयन किया जाता है :
ओवरलोड रिज़ॉल्यूशन का उपयोग रूपांतरण फ़ंक्शन का चयन करने के लिए किया जाता है।
जब क्लास के सदस्य कार्यों के लिए अधिभार संकल्प की बात आती है, तो एक विशेष "क्विक" होता है: निहित वस्तु पैरामीटर "।
प्रति C ++ 11, 13.3.1 [over.match.funcs] ,
[...] दोनों स्थिर और गैर-स्थैतिक सदस्य कार्यों में एक अंतर्निहित वस्तु पैरामीटर है [...]
गैर-स्थैतिक सदस्य कार्यों के लिए इस पैरामीटर का प्रकार-क्लाज 4- के लिए-रिकॉर्डिंग कहां है:
जहाँ X वह वर्ग है जिसमें फ़ंक्शन एक सदस्य है और cv सदस्य फ़ंक्शन घोषणा पर cv-योग्यता है।
इसका मतलब यह है कि (प्रति C ++ 11, 13.3.1.5/2 [over.match.conv] ), रूपांतरण सूची के आरंभ में,
[t] उन्होंने तर्क सूची में एक तर्क दिया है, जो कि आरम्भिक अभिव्यक्ति है। [नोट: इस तर्क की तुलना रूपांतरण कार्यों के निहित वस्तु पैरामीटर के खिलाफ की जाएगी। ध्यान दें]
अधिभार संकल्प के लिए उम्मीदवार कार्य कर रहे हैं:
operator bool (B2 const &);
operator int (B2 &);
जाहिर है, operator int ()
एक बेहतर मैच है अगर योग्यता रूपांतरण के लिए आवश्यक रूप B2
से गैर-स्थिर ऑब्जेक्ट का उपयोग करके रूपांतरण का अनुरोध किया जाता है operator bool ()
।
यदि दोनों रूपांतरण फ़ंक्शंस एक ही कॉन्स्टेबल योग्यता साझा करते हैं, तो उन फ़ंक्शन का अधिभार रिज़ॉल्यूशन चाल नहीं करेगा। इस स्थिति में, रूपांतरण (अनुक्रम) रैंकिंग जगह में आती है।
3. क्यों operator bool ()
चुना जाता है जब दोनों रूपांतरण फ़ंक्शन एक ही कॉन्स्टेबल योग्यता साझा करते हैं?
से रूपांतरण B2
करने के लिए bool
एक उपयोगकर्ता-निर्धारित रूपांतरण अनुक्रम (है सी ++ 11, 13.3.3.1.2 / 1 [over.ics.user] )
एक उपयोगकर्ता-परिभाषित रूपांतरण अनुक्रम में एक प्रारंभिक मानक रूपांतरण अनुक्रम होता है, जिसके बाद उपयोगकर्ता-निर्धारित रूपांतरण होता है और उसके बाद दूसरा मानक रूपांतरण अनुक्रम होता है।
[...] यदि उपयोगकर्ता-परिभाषित रूपांतरण एक रूपांतरण फ़ंक्शन द्वारा निर्दिष्ट किया गया है, तो प्रारंभिक मानक रूपांतरण अनुक्रम स्रोत प्रकार को रूपांतरण फ़ंक्शन के अंतर्निहित ऑब्जेक्ट पैरामीटर में परिवर्तित करता है।
C ++ 11, 13.3.3.2/3 [over.ics.rank]
[...] बेहतर रूपांतरण अनुक्रम और बेहतर रूपांतरण के आधार पर निहित रूपांतरण अनुक्रमों के आंशिक क्रम को परिभाषित करता है।
[...] उपयोगकर्ता-परिभाषित रूपांतरण अनुक्रम U1 एक अन्य उपयोगकर्ता-परिभाषित रूपांतरण अनुक्रम U2 की तुलना में बेहतर रूपांतरण अनुक्रम है, यदि उनमें एक ही उपयोगकर्ता-निर्धारित रूपांतरण फ़ंक्शन या कंस्ट्रक्टर या समग्र आरंभ होता है और U1 का दूसरा मानक रूपांतरण अनुक्रम इससे बेहतर है U2 का दूसरा मानक रूपांतरण अनुक्रम।
दूसरा मानक रूपांतरण मामले की है operator bool()
है bool
के bool
मामले में (पहचान रूपांतरण) जबकि दूसरा मानक रूपांतरण की operator int ()
है int
करने के लिए bool
जो एक बूलियन रूपांतरण है।
इसलिए, रूपांतरण अनुक्रम, का उपयोग operator bool ()
करना बेहतर है, यदि दोनों रूपांतरण फ़ंक्शन एक ही कॉन्स्टेबल योग्यता साझा करते हैं।