c++ - SFINAE with invalid function-type or array-type parameters? -
कृपया इस कोड पर विचार करें:
टेम्पलेट & lt; typename T & gt; चार (और एफ (टी [1])) [1]; टेम्पलेट & lt; typename T & gt; चार (और एफ (...)) [2]; Int main () {char c [sizeof (f & lt; शून्य () & gt; (0)) == 2]; } मुझे उम्मीद है कि यह एसफिनाई कर रहा है और दूसरे अधिभार को समाप्त कर रहा है, चूंकि T में T [1] पैदावार
शून्य [1] () कौन सा अमान्य प्रकार है, बिल्कुल। पैरामीटर प्रकारों (एरे-> पॉइंटर) को समायोजित करने के बाद टेम्पलेट मापदंडों को फ़ंक्शन मापदंडों में बदलने और 14.8.2 [temp.deduct] जैसी वैध परिणाम प्रकारों की जांच करने के बाद किया जाता है।
लेकिन दोनों आने वाले और जीसीसी विफल ऊपर संकलित करें दोनों विभिन्न निदान के साथ
कमू का कहना है:
"कमओटेस्ट सी", पंक्ति 2: त्रुटि: कार्यों की सरणी अनुमति नहीं है
char (& amp; एफ (टी [1] )) [1];
जीसीसी कहती है (संस्करण <कोड> 4.3.3 ):
त्रुटि: आईएसओ सी ++ शून्य-आकार की सरणी को प्रतिबंधित करता है
c
अर्थ, जीसीसी विकल्प के लिए असफल नहीं है, लेकिन यह f का पहला अधिभार चुन लेता है, <1> की sizeof लौटाने के बजाय इसे कमयू जैसे सामने लाने में विफल रहने के बजाय
क्या कंपाइलर सही है और क्या मेरा कोड बिल्कुल मान्य है? कृपया अपने उत्तर में उचित मानक खंड का संदर्भ लें या उद्धृत करें। धन्यवाद!
अपडेट : मानक में 14.8.2 / 2 पर सूची में ऐसा एक उदाहरण है। मुझे नहीं पता कि मैंने इसे पहले क्यों अनदेखा किया है:
टेम्पलेट & lt; class T & gt; Int f (टी [5]); Int I = f & lt; int & gt; (0); Int j = f & lt; शून्य & gt; (0); // अमान्य सरणी हालांकि उदाहरण केवल सूचनात्मक है, यह उन सभी रहस्यमय पैराग्राफों का इरादा दिखाता है और यह दिखता है कि ऊपर कोड को काम करना चाहिए और पहले ओवरलोड को अस्वीकार करना चाहिए।
एक छोटी सी नोट, हालांकि बहुत दुर्लभ है, मुझे कुछ अवसर मिल गए हैं जहां मुझे विश्वास है कि कम्यु संकलक को यह गलत है - हालांकि , इन अवसरों इतने दुर्लभ हैं कि इसकी हमेशा कीमतें डबल और ट्रिपल आपकी मान्यताओं की जांच कर रही हैं!मेरे पास जी ++ के व्यवहार के लिए कोई कारण हो सकता है मुझे यकीन नहीं है कि यह निर्दिष्ट किया गया है कि पैरामीटर प्रकार समायोजित किए गए हैं:
निम्नलिखित पर विचार करें:
टेम्पलेट & lt; typename T & gt; संरचना एक {शून्य बार (टी [10]); }; टेम्पलेट & lt; typename T & gt; 'ए' के लिए "टी [10]" क्षय के रूप में 'बार' की परिभाषा कानूनी है, ए और एलटी; टी & gt; :: बार (टी *) {} कानूनी है। मैं मानक में कुछ भी नहीं देखता जो कंपाइलर को टेम्प्लेट घोषणापत्र के विरुद्ध 8.3.5 के समायोजन करने से रोकता है, और यह ओवरलोड मिलान के मामले में भी प्रदर्शन में सुधार करता है।
इसे अपने उदाहरण के लिए आवेदन करना, जी ++ शायद इसका इलाज कर सकता है:
टेम्पलेट & lt; typename T & gt; चार (और एफ (टी *)) [1]; टेम्पलेट & lt; typename T & gt; चार (और एफ (...)) [2]; Int main () {char c [sizeof (f & lt; शून्य () & gt; (0)) == 2]; } उपरोक्त में, प्रतिस्थापन पैरामीटर कार्य की एक सरणी के बजाय कार्य करने के लिए एक कानूनी संकेतक है।
तो, मेरे लिए सवाल है - है ऐसा कुछ है जो फ़ंक्शन मापदंडों (8.3.5) के लिए दो बार समायोजन को प्रतिबंधित करता है?
व्यक्तिगत रूप से, मुझे लगता है कि समायोजन को दो बार होने की अनुमति देने के लिए यह समझ में आता है क्योंकि अन्यथा यह फ़ंक्शन टेम्पलेट ओवरलोड के मिलान को जटिल बनाता है < / P>
अंत में, मुझे लगता है कि जी ++ के लिए यह मान्य है कि यह कैसे सरणी पैरामीटर को क्षय करने के साथ-साथ पहली अधिभार का चयन करता है, और कम्यू फ़ैर्रे के लिए कटाव विफलता नहीं है।
< P> बेशक अब इसका मतलब है कि (यदि कमो को तय किया गया था) तो प्रत्येक कंपाइलर एक अलग अधिभार चुन लेगा और अभी भी मानकों के अनुरूप होगा! : (संपादित करें:
बस मेरी बात को समझाने के लिए, निम्न कोड पर विचार करें:
टेम्पलेट & lt; typename ट & gt; void foo (T *); टेम्पलेट & lt; typename T & v; void foo (T * कॉन्स्ट); टेम्पलेट & lt; typename T & gt; void foo (T []); टेम्पलेट & lt; typename T & v; void foo (T [10] ); टेम्पलेट & lt; typename T & gt; void foo (T [100]); शून्य बार () {foo & lt; void ()> (0);} यहां, foo है घोषित किया गया है और इसे कई बार पुनः घोषित किया गया है। कौन सा घोषणा, और इसलिए पैरामीटर प्रकार, क्या कंपाइलर 14.8.2 में सूचीबद्ध नियमों को लागू करना चाहिए?
मेरा मुद्दा यह है कि मानक ऊपर के बारे में कुछ नहीं कहता है मैं यह भी कहता हूं कि इस पर किसी भी शब्द को इसे "अपरिभाषित" या "कार्यान्वयन परिभाषित" व्यवहार के रूप में छोड़ना होगा।
Comments
Post a Comment