void fun(int*);  // #1
void fun(int const*);  //#2
int main(){
  int* ptr = nullptr;
  fun(ptr);
}

उपरोक्त उदाहरण पर विचार करें, अधिभार संकल्प #1 और #2 में सर्वोत्तम व्यवहार्य फ़ंक्शन का चयन करेगा। यह इसकी एक शाखा है प्रश्न, अर्थात्, [over.ics.rank#3.2.1] और [over.ics.rank#3.2.5] के बीच अस्पष्ट।

प्रासंगिक नियम हैं:

over.ics.रैंक#3.2.1

S1, S2 का एक उचित अनुवर्ती है ([over.ics.scs] द्वारा परिभाषित विहित रूप में रूपांतरण अनुक्रमों की तुलना, किसी भी Lvalue परिवर्तन को छोड़कर; पहचान रूपांतरण अनुक्रम को किसी भी गैर-पहचान रूपांतरण के बाद के रूप में माना जाता है अनुक्रम) या, यदि नहीं तो

IMO, S1 #1 का पहचान रूपांतरण है जबकि S2 #2 का योग्यता रूपांतरण है, उपरोक्त नियम यह कहता प्रतीत होता है कि Identity conversion किसी से बेहतर है गैर-पहचान रूपांतरण जिसमें एक सटीक मिलान रैंक है।

हालांकि, इस मामले से संबंधित एक और प्रासंगिक नियम है, वह है:
over.ics.rank#3.25

S1 और S2 केवल उनके योग्यता रूपांतरण ([conv.qual]) में भिन्न होते हैं और क्रमशः समान प्रकार T1 और T2 प्राप्त करते हैं, जहां T1 को योग्यता रूपांतरण द्वारा T2 में परिवर्तित किया जा सकता है।

IMO, यह नियम कहता है कि S1 और S2 सभी के पास योग्यता रूपांतरण है, लेकिन ये रूपांतरण भिन्न हैं और T1 को T2 में बदला जा सकता है योग्यता रूपांतरण द्वारा।

मेरे उदाहरण में, int* से int const* तक बिल्कुल एक योग्यता रूपांतरण है। हालांकि, एक एज-केस int* से int* तक है, क्या इस रूपांतरण को एक पहचान रूपांतरण या योग्यता रूपांतरण माना जाता है? conv.qual#3 की परिभाषा के अनुसार, यह हो सकता है। हालांकि, कड़ाई से बोलते हुए, इसे पहचान रूपांतरण कहा जाना चाहिए।

प्रश्न 1:

क्या नियम के बारे में मेरी समझ [over.ics.rank#3.2.5] सही है? या, क्या इसका मतलब यह है कि, S1 में एक खाली रूपांतरण (जैसे पहचान रूपांतरण) हो सकता है, जब योग्यता रूपांतरण द्वारा T1 को T2 में बदला जा सकता है? (पॉइंटर्स के लिए पहचान रूपांतरण शामिल करें)

प्रश्न 2:

क्या एक सूचक प्रकार के पहचान रूपांतरण को योग्यता रूपांतरण या सिर्फ एक पहचान रूपांतरण माना जाता है? दूसरे शब्दों में, क्या [over.ics.rank#3.2.1] या [over.ics.rank#3.2.5] मेरे उदाहरण पर लागू होते हैं?

0
xmh0511 14 पद 2020, 05:11
1
मैं प्रश्नोत्तर से लिंक करने की अनुशंसा करता हूं जिसने आपके प्रश्न को प्रेरित किया। इस तरह का एट्रिब्यूशन सामान्य रूप से अच्छा अभ्यास है। यह पाठकों को आपके प्रश्न को समझने के लिए उपयोगी संदर्भ प्रदान करता है, और यह स्पष्ट करने में मदद कर सकता है कि मानक नियमों के किन हिस्सों को समझने में आपको कठिनाई हो रही है। इससे अधिक अनुरूप, उच्च गुणवत्ता वाले उत्तर प्राप्त हो सकते हैं, जिससे संपूर्ण प्रश्नोत्तर की गुणवत्ता में सुधार होता है।
 – 
cigien
14 पद 2020, 05:17
हाँ, एक अच्छा सुझाव। मैं ऐसा करने जा रहा था।
 – 
xmh0511
14 पद 2020, 05:23
संपादन के लिए धन्यवाद, यह प्रश्न में काफी सुधार करता है।
 – 
cigien
14 पद 2020, 05:24
मुझे लगता है कि यह सवाल एक किनारे का मामला है। हो सकता है, [over.ics.rank#3.2.1] और [over.ics.rank#3.2.5] सभी इस अधिभार समाधान को संसाधित कर सकें। केवल, [over.ics.rank#3.2.1] पहले इस मामले में लागू होते हैं। इसके लिए आपके और मेरे बीच चर्चा के बारे में यह मेरी राय है प्रश्न एवं उत्तर
 – 
xmh0511
14 पद 2020, 05:38

1 उत्तर

सबसे बढ़िया उत्तर

int* से int* तक के मानक रूपांतरण अनुक्रम में योग्यता रूपांतरण नहीं होता है।

यह [over.ics.best.general]/8 द्वारा स्पष्ट किया गया है:

यदि पैरामीटर प्रकार के तर्क से मेल खाने के लिए किसी रूपांतरण की आवश्यकता नहीं है, तो अंतर्निहित रूपांतरण अनुक्रम मानक रूपांतरण अनुक्रम है जिसमें पहचान रूपांतरण ([over.ics.scs]) शामिल है।

इसका अनुमान अन्य परिच्छेदों से भी लगाया जा सकता है। उदाहरण के लिए, [over.best.ics.general]/1 देखें:

एक अंतर्निहित रूपांतरण अनुक्रम एक फ़ंक्शन कॉल में एक तर्क को फ़ंक्शन के संबंधित पैरामीटर के प्रकार में परिवर्तित करने के लिए उपयोग किए जाने वाले रूपांतरणों का एक क्रम है। रूपांतरणों का क्रम एक अंतर्निहित रूपांतरण है जैसा कि [रूपांतरण] में परिभाषित किया गया है, जिसका अर्थ है कि यह किसी वस्तु या संदर्भ के आरंभीकरण के नियमों द्वारा एकल अभिव्यक्ति ([dcl.init], [dcl.init.ref]) द्वारा नियंत्रित होता है।

और [over.ics.best.General]/6:

जब पैरामीटर प्रकार एक संदर्भ नहीं है, तो निहित रूपांतरण अनुक्रम तर्क अभिव्यक्ति से पैरामीटर की प्रतिलिपि-आरंभीकरण मॉडल करता है। निहित रूपांतरण अनुक्रम वह है जो तर्क अभिव्यक्ति को पैरामीटर के प्रकार के प्रचलन में बदलने के लिए आवश्यक है।
...

अर्थात्, int* -> int* के लिए सही अंतर्निहित रूपांतरण अनुक्रम वह है, जो भाषा के नियमों के अनुसार, आमतौर पर तब बनता है जब int * को int* से कॉपी-इनिशियलाइज़ किया गया है। इस मामले में, [dcl.init.general]/16.9 लागू होता है:

अन्यथा, प्रारंभ की जा रही वस्तु का प्रारंभिक मान प्रारंभकर्ता अभिव्यक्ति का (संभवतः परिवर्तित) मान है। एक मानक रूपांतरण अनुक्रम ([रूपांतरण]) का उपयोग किया जाएगा, यदि आवश्यक हो, तो प्रारंभकर्ता अभिव्यक्ति को गंतव्य प्रकार के cv-अयोग्य संस्करण में बदलने के लिए; उपयोगकर्ता-परिभाषित रूपांतरणों पर विचार नहीं किया जाता है। यदि रूपांतरण नहीं किया जा सकता है, तो आरंभीकरण गलत है। एक बिट-फ़ील्ड को उस मान के साथ प्रारंभ करते समय जिसका वह प्रतिनिधित्व नहीं कर सकता, बिट-फ़ील्ड का परिणामी मान कार्यान्वयन-परिभाषित होता है।

कोई रूपांतरण आवश्यक नहीं है क्योंकि int* और int* पहले से ही एक ही प्रकार के हैं, इसलिए कोई रूपांतरण नहीं किया जाता है। यह अपने आप में int* से योग्यता रूपांतरण नहीं है।

इसका मतलब है कि [over.ics.rank]/3.2.1 निश्चित रूप से सकारात्मक है: S1 पहचान रूपांतरण अनुक्रम है (न कि एक निहित रूपांतरण अनुक्रम जिसमें एक निरर्थक योग्यता रूपांतरण शामिल है) इसलिए यह S2 का अनुवर्ती है। .

1
Brian Bi 14 पद 2020, 05:48
धन्यवाद, आपकी समझ लगभग मेरी जैसी ही है। हालांकि, [dcl.init.general]/16.9 के लिए, यहां तक ​​कि लक्ष्य प्रकार स्रोत प्रकार के समान है, मुझे लगता है कि lvalue-to-rvalue रूपांतरण अभी भी मूल्य को पढ़ने के लिए स्रोत प्रारंभकर्ता पर लागू होता है (मूल्यांकन का मूल्यांकन प्रारंभ होगा परिणाम वस्तु)। या int* const से int* तक।(lvalue-to-rvalue अभी भी लागू होता है)। हालांकि, जैसा कि [over.ics.rank#3.2.1] कहता है, lvalue-to-rvalue रैंकिंग के मूल्यांकन में भाग नहीं लेता है। तो, lvalue-to-rvalue रैंकिंग को प्रभावित नहीं करता
 – 
xmh0511
14 पद 2020, 06:29