2015-03-21 8 views
10

इस कोड पर विचार करें:हमें अपूर्ण प्रकार का पता क्यों लेने की अनुमति है?

class Addressable; 
class Class1 { void foo(Addressable &a) { (void) &a; } }; // OK 
class Addressable { void *operator &() { return this; } }; 
class Class2 { void foo(Addressable &a) { (void) &a; } }; // Error: operator & private 

क्यों सी ++ एक अधूरी संदर्भ प्रकार के पते लेने की अनुमति देते हैं?

क्या ऊपर दिखाया गया यह संभावित रूप से अवैध नहीं हो सकता है? क्या यह जानबूझकर है?

+4

मुझे लगता है कि बेहतर सवाल यह है कि "सी ++ पहली जगह में' & 'के ओवरलोडिंग की अनुमति क्यों देता है": डी –

+0

मुझे नहीं पता था कि आप 'ऑपरेटर और() 'अधिभारित कर सकते हैं। कभी-कभी मुझे लगता है कि सी ++ देवताओं को * बहुत अधिक * देता है। – tenfour

+0

@tenfour: मैं सचमुच केवल एक परिस्थिति के बारे में सोच सकता हूं जिसमें यह उपयोगी है, और वह तब होता है जब लैम्ब्डा नोटेशन में ऑपरेशन के पते का प्रतिनिधित्व करता है, उदाहरण के लिए 'Foo [और _ 1]'। – Mehrdad

उत्तर

5

हां, यह जानबूझकर है, और ब्रेकेज की संभावना operator& ओवरलोडेड है।

अपूर्ण प्रकारों का पता लेना सी ++ से बहुत पहले संभव है। सी में, किसी भी ब्रेकेज का बिल्कुल कोई जोखिम नहीं है, क्योंकि & ओवरलोड नहीं किया जा सकता है।

सी ++ ने पहले वैध प्रोग्रामों को अनावश्यक रूप से तोड़ने का विकल्प नहीं चुना है, और बस निर्दिष्ट किया है कि अगर एक अपूर्ण प्रकार & ऑपरेटर ओवरलोडेड हो जाता है, तो यह निर्दिष्ट नहीं है कि अधिभारित ऑपरेटर का उपयोग किया जाता है या नहीं।

का हवाला देते हुए N4140:

5.3.1 एकल ऑपरेटरों [expr.unary.op]

तो & अधूरा वर्ग प्रकार का एक lvalue और पूर्ण प्रकार पर लागू होता है वाणी operator&(), यह निर्दिष्ट नहीं है कि ऑपरेटर का अंतर्निहित अर्थ है या ऑपरेटर फ़ंक्शन कहा जाता है।

यह एक वर्ग वर्तमान में घोषित किया जा रहा करने के लिए भी लागू करने के लिए व्याख्या की जा सकती है और यहां तक ​​कि जब operator& की घोषणा पहले से ही देखा गया है:

extern struct A a; 
struct A { 
    int operator&(); 
    decltype(&a) m; // int, or A *? 
}; 
int main() { 
    return A().m; // only valid if m is int 
} 

यहाँ, जीसीसी m प्रकार A * देता है और कार्यक्रम को खारिज कर दिया , लेकिन क्लैंग इसे int टाइप करता है और इसे स्वीकार करता है।

+0

+1 वाह। आखिरी वाक्य तब भी होती है जब टाइप अपूर्ण होने पर '&' का उपयोग नहीं किया जाता है? दूसरे शब्दों में, क्या संकलक हर समय अधिभारित '& 'को अनदेखा कर सकता है? – Mehrdad

+0

@ मेहरदद मैं समझ नहीं पा रहा हूं कि उस टिप्पणी से आपका क्या मतलब है। यदि संकलक देखता है कि प्रकार अपूर्ण है, तो ओवरलोडेड 'ऑपरेटर' की तलाश करने का प्रयास विफल हो जाएगा, इसलिए केवल अंतर्निहित ऑपरेटर ही पाया जा सकता है। लेकिन साथ ही, प्रोग्राम में कौन से बिंदुओं को अभी तक पूरा नहीं किया गया है, इस पर ट्रैक रखने के लिए एक कंपाइलर की आवश्यकता नहीं है, और यदि संकलन ऊपर से नीचे तक सख्ती से नहीं होता है, तो यह प्रकार पूर्ण रूप से देख सकता है (और ओवरलोडेड ऑपरेटर ढूंढें) भले ही आप इसकी अपेक्षा न करें। – hvd

+0

मैं बस इतना कह रहा हूं कि आपका आखिरी वाक्य यह स्पष्ट नहीं करता है कि वास्तव में व्यवहार निर्दिष्ट नहीं होता है: क्या यह हमेशा निर्दिष्ट नहीं होता है, या केवल निर्दिष्ट नहीं किया जाता है जब '&' अभी तक परिभाषित नहीं किया गया है? – Mehrdad

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