2017-12-28 81 views
8

वहाँ वैश्विक समारोह (सिर्फ उदाहरण) है:ओवरलोडेड फ़ंक्शन को हटा रहा है। सी ++ 11। अतिभारित कॉल ... अस्पष्ट है

void func(int i) 
{ 
    std::cout << i + 100 << std::endl; 
} 

मुझे लगता है कि चार तर्क के साथ इस कार्यप्रणाली को कॉल किसी भी मतलब नहीं है तो मैं हटाने का प्रयोग करें:

void func(char) = delete; 

तो मैं उम्मीद करते हैं कि निम्न कॉल संभव हो जाना चाहिए:

func(1); 
func(3.1); 
func(true); 

और चार तर्क के साथ फोन forbiden किया जाना चाहिए:

func('a'); 

लेकिन यह सच नहीं है। जब func('a') बुला मैं अपेक्षा के अनुरूप मिल:

error: use of deleted function ‘void func(char)’ 

लेकिन func(2.3) बुला दौरान मैं:

error: call of overloaded ‘func(double)’ is ambiguous 

मैं यह त्रुटि क्यों मिलता है? चार तर्कों के साथ फ़ंक्शन को हटाए बिना डबल को int और func (int) में परिवर्तित किया गया था, अब इसे क्यों प्रतिबंधित किया गया है?

+0

_ "मुझे यह त्रुटि क्यों मिलती है?" _ आप जानते हैं कि 'char' को स्वचालित रूप से' int' में परिवर्तित किया जा सकता है और बदले में 'डबल' हो सकता है? – user0042

+5

आपके द्वारा ** संपादित किए गए सब कुछ ** संपादित ** आपके प्रश्न का उत्तर जैसा लगता है। यदि यह आपका उत्तर है, तो कृपया इसे प्रश्न से हटा दें और * इसे उत्तर के रूप में पोस्ट करें *। यदि, ऐसा लगता है, तो आप बस एक मौजूदा को प्रतिबिंबित कर रहे हैं, डुप्लिकेट उत्तर पोस्ट न करें; बस इसे अपने प्रश्न से हटा दें। –

उत्तर

12

जब आप

func(2.3) 

फोन आप कार्य करने के लिए एक double गुजरती हैं। उम्मीदवारों की सूची, दोनोंfunc(int) और func(char) शामिल अधिभार संकल्प होता है beforedelete kicks in के रूप में:

समारोह ओवरलोड हो गया है, तो अधिभार संकल्प पहली जगह लेता है, और कार्यक्रम केवल बीमार का गठन करता है, तो नष्ट कर दिया समारोह था चयनित रेफरी: cppreference.com, सटीक मानक उद्धरणों के लिए Avishai's answer देखें।

अब doublechar और int, इसलिए अस्पष्टता में दोनों परिवर्तित किया जा सकता है।

चार तर्कों के साथ फ़ंक्शन को हटाए बिना डबल को int और func (int) में परिवर्तित किया गया था, अब इसे क्यों प्रतिबंधित किया गया है?

तुम भी delete ing char संस्करण के बिना एक अस्पष्टता त्रुटि मिलती है, को देखने को लाइव here। बेशक अगर आप केवल func(int) को परिभाषित करते हैं, तो वहां कोई अस्पष्टता नहीं होगी, इसलिए double खुशी से int में परिवर्तित हो जाएगा।

+0

मुझे [इस] में अस्पष्टता त्रुटि नहीं मिली है (http://coliru.stacked-crooked.com/a/920af47ca988ed2e) उदाहरण। –

+1

@AdamStepniak संपादित देखें। आपके लिंक में आपके पास केवल एक घोषणा है, 'func (int)', इसलिए कोई रूपांतरण अस्पष्टता नहीं है। यदि आप 'func (char)' जोड़ते हैं, कोई फर्क नहीं पड़ता कि 'हटाएं' या नहीं, तो आपको जवाब में उल्लिखित एक अस्पष्टता मिलेगी। याद रखने की बात यह है कि 'डिलीट' को ** ओवरलोड रिज़ॉल्यूशन के बाद हल किया गया है, http://en.cppreference.com/w/cpp/language/function#Deleted_functions देखें, इसलिए अस्पष्टताएं होती हैं जैसे कि आप पहले लिख रहे थे सी ++ 11 कोड। – vsoftco

0

यह अभी भी संदिग्ध है, क्योंकि संकलक हटाए गए कार्यों की जांच करने से पहले ओवरलोड को हल करने का प्रयास करता है। देखें:

§8.4।3 हटाए गए परिभाषाएं

एक प्रोग्राम जो इसे घोषित करने के अलावा, एक हटाए गए फ़ंक्शन को स्पष्ट रूप से या स्पष्ट रूप से संदर्भित करता है, बीमार है। [ नोट: इसमें फ़ंक्शन को निहित या स्पष्ट रूप से कॉल करना और फ़ंक्शन में पॉइंटर या पॉइंटर-टू-सदस्य बनाना शामिल है। यह अभिव्यक्तियों के संदर्भों के लिए भी लागू होता है जिन्हें संभावित रूप से मूल्यांकन नहीं किया जाता है। यदि कोई फ़ंक्शन अधिभारित है, तो इसे केवल तभी संदर्भित किया जाता है जब फ़ंक्शन को ओवरलोड रिज़ॉल्यूशन द्वारा चुना जाता है। - अंत टिप्पणी ]

§13.3.3.1 अंतर्निहित रूपांतरण दृश्यों:

अंतर्निहित रूपांतरण दृश्यों केवल प्रकार, सीवी-योग्यता, और का मूल्य वर्ग तर्क और कैसे इन को लेकर चिंतित हैं पैरामीटर के संबंधित गुणों से मेल खाने के लिए परिवर्तित कर रहे हैं। अन्य गुण, जैसे जीवनकाल, भंडारण वर्ग, संरेखण, तर्क की पहुंच, चाहे तर्क थोड़ा-सा क्षेत्र है, और कोई फ़ंक्शन हटा दिया गया है (8.4.3), अनदेखा किया जाता है। इसलिए, हालांकि एक अंतर्निहित रूपांतरण अनुक्रम किसी दिए गए तर्क-पैरामीटर जोड़ी के लिए परिभाषित किया जा सकता है, तर्क से रूपांतरण पैरामीटर को अंतिम विश्लेषण में अभी भी खराब बना दिया जा सकता है।

+0

कंपाइलर _didn't_ 'func (char)' का चयन करें, और तथ्य यह है कि फ़ंक्शन हटा दिया गया था समस्या के लिए 100% अप्रासंगिक है। –

1

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

काम करने के लिए ओवरलोड रिज़ॉल्यूशन के लिए, यह उम्मीदवार कार्यों का एक सेट बनाता है, फिर देखता है जिसमें पैरामीटर के सेट के लिए सबसे छोटा रूपांतरण पथ है। जहां तक ​​नियम चलते हैं, सभी अंतर्निहित संख्यात्मक प्रकार एक "बराबर" रूपांतरण होते हैं। इसलिए, यदि आप 2.5 के साथ कॉल करते हैं, जो एक डबल है, तो इसे समान रैंकिंग के साथ समान रूप से एक char या int में परिवर्तित करना चाहिए और कॉल को संदिग्ध करना चाहिए।

+0

नोट: कुछ ऐसे मामले हैं जहां हटाए गए फ़ंक्शन ओवरलोड रिज़ॉल्यूशन में भाग नहीं लेते हैं (आमतौर पर इसमें कक्षा विशेष सदस्य फ़ंक्शंस शामिल होते हैं); लेकिन ओपी केस उस स्पष्टीकरण के लिए –

+0

@ एमएम धन्यवाद में से एक नहीं है। –

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