2013-05-13 5 views
10

में 5.1.1 सी के/3 ++ मानक [expr.prim.general]`* यह बाहरी सदस्य कार्य निकाय?

अन्य संदर्भों में वस्तु अभिव्यक्ति के विपरीत, * इस वर्ग के सदस्य पहुँच के प्रयोजनों के बाहर के लिए पूर्ण प्रकार का होना आवश्यक नहीं है सदस्य समारोह शरीर। घोषणा के लिए केवल 0 सदस्यों के पहले घोषित किया गया है।

और फिर इस उदाहरण:

struct A { 
    char g(); 
    template<class T> auto f(T t) -> decltype(t + g()) 
    { return t + g(); } 
}; 
template auto A::f(int t) -> decltype(t + g()); 

आप उद्धरण और उदाहरण व्याख्या कर सकते हैं? यहां वास्तव में क्या दिखाया जा रहा है?

+1

मेरा मानना ​​है कि यह 'एक :: g' के उपयोग को संदर्भित करता है अपने शरीर के बजाय 'एफ' के हस्ताक्षर में। यह कंपाइलर लेखकों के लिए चीजों को जटिल करता है, क्योंकि आपको 'ए 'जी' पर अधिभार रिज़ॉल्यूशन (संभावित रूप से) अधिभार रिज़ॉल्यूशन करने के लिए कहा जाता है, भले ही 'ए' पूरी तरह से परिभाषित नहीं किया गया हो। इससे पहले, एक सामान्य बात यह थी कि पहले सभी घोषणाओं (विधियों और सदस्यों के) को पार्स करें और फिर विधियों के निकायों को पार्स करने के लिए "पूरी तरह परिभाषित" 'ए' का उपयोग करें। –

+0

@MaththieuM .: ध्यान दें कि यह फ़ंक्शन बॉडी के बाहर है। क्लास विनिर्देशक को पार्स करने के बाद भी आपको इनलाइन फ़ंक्शन निकायों की पार्सिंग को रोकना होगा। –

उत्तर

4

इसका मतलब है कि आप एक वर्ग परिभाषा के भीतर बाहर समारोह निकायों this के माध्यम से सदस्यों का उपयोग कर सकते हैं, या तो स्पष्ट या परोक्ष,। उस बिंदु पर, प्रकार अपूर्ण है, और आमतौर पर आप अपूर्ण प्रकार के सदस्यों तक नहीं पहुंच सकते हैं।

लेकिन आप केवल सदस्य कार्य घोषणा के प्रतिबंधित हिस्सों में ही ऐसा कर सकते हैं; पिछले वाक्य कहते हैं के बारे में this:

यह पहले वैकल्पिक सीवी-क्वालीफायर-सेक

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

गैर-स्थैतिक सदस्य से जुड़े अभिव्यक्ति के प्रकार को प्राप्त करने के लिए आपको पिछली वापसी प्रकार में decltype का उपयोग करते समय ऐसा करने की आवश्यकता हो सकती है। उदाहरण पिछला रिटर्न प्रकार में g() तक पहुंचने के लिए this का उपयोग करके स्पष्ट रूप से इसका प्रदर्शन करता है। अगर यह decltype(t + this->g()) के रूप में लिखा गया तो यह स्पष्ट होगा कि क्या दिखाया जा रहा था।

+0

करते समय अपूर्ण है क्या यह एकमात्र एप्लिकेशन है? 'ट्रेलिंग-रिटर्न-टाइप' में 'decltype''? (या मुझे पैरामीटर घोषणा में भी लगता है) –

+0

@ user1131467: मुझे नहीं पता। यह एकमात्र ऐसा है जिसे मैं तुरंत सोच सकता हूं, लेकिन मैं सोमवार को बहुत कल्पना नहीं कर रहा हूं। –

+0

@ user1131467: रिटर्न प्रकार पीछे पीछे नहीं है। आप 'decltype (this) 'का उपयोग कर सकते हैं, भले ही रिटर्न टाइप पीछे नहीं है, या पैरामीटर घोषणा –

6

यह वास्तव में क्या उदाहरण है? यहां कौन सा कथन प्रदर्शित किया जा रहा है?

बयान का प्रदर्शन किया जा रहा है:

अन्य संदर्भों में वस्तु अभिव्यक्ति के विपरीत, * यह पूरा प्रकार की होनी चाहिए वर्ग के सदस्य एक्सेस (5.2.5) के प्रयोजनों के लिए आवश्यक नहीं है बाहर सदस्य समारोह शरीर।

सदस्य समारोह के शरीर के बाहर g() को एक मंगलाचरण, जो this->g() का मतलब नहीं है। वहां, *this का प्रकार (यानी A) पूरा नहीं हुआ है।

एक वर्ग वर्ग के समापन } में एक पूरी तरह से परिभाषित ऑब्जेक्ट प्रकार (3.9) (या पूर्ण प्रकार) माना जाता है:

प्रति पैरा सी ++ 11 स्टैंडर्ड के 9.2/2

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

+0

हां और 'पिछला-वापसी-प्रकार' उस सूची में नहीं है। –

+0

@ user1131467: ठीक है, तो यह 'अप-> जी() ' –

2

सबसे पहले, सभी सदस्य पहुँच भाव संकलक से बदल रहे हैं:

struct X{ 
    int a; 
    void f(){} 
    void g(int b){ 
    int x = a + b; // actually: int x = (*this).a + b 
    f(); // actually: (*this).f(); 
    } 
}; 

§9.3.1 [class.mfct.non-static] p3

[...] आईडी अभिव्यक्ति एक वर्ग के सदस्य पहुँच में तब्दील हो जाता . ऑपरेटर के बाईं ओर पोस्टफिक्स-अभिव्यक्ति के रूप में (*this) (9.3.2) का उपयोग करके अभिव्यक्ति (5.2.5)। [...]

अब, मानक से उदाहरण एक सदस्य समारोह किसी अन्य सदस्य समारोह के शरीर के बाहर कहता है, पीछे-रिटर्न-प्रकार में। और वह कॉल भी तब्दील हो जाता है:

template<class T> auto f(T t) -> decltype(t + (*this).g()) 
{ return t + (*this).g(); } 

और एक सदस्य समारोह शरीर के बाहर, *this स्पष्ट रूप से एक अधूरी प्रकार है। इसका मतलब यह है कि आप केवल ऐसे नाम हैं जो उपयोग करने से पहले घोषित किया गया है का उपयोग कर सकते हैं - लेकिन वह हिस्सा *this उपयोग करने के लिए केवल लागू नहीं होता:

struct X{ 
    using typeA = int; 
    typeA f(); // OK, 'typeA' has been declared before 

    typeB g(); // Error: 'typeB' not declared before usage 
    using typeB = float; 
}; 
+0

मुझे लगता है कि कक्षा विनिर्देशक के अंदर 'ए :: एफ' की इनलाइन परिभाषा में अधूरा है, हालांकि मुझे लगता है कि यह' ए :: एफ' की घोषणा में पूर्ण है जो बंद ब्रेस का पालन करता है। –

+0

किसी सदस्य फ़ंक्शन परिभाषा के शरीर के अंदर, '* यह' हमेशा एक पूर्ण प्रकार माना जाता है,' §9.2/2' देखें। – Xeo

+0

हां लेकिन पिछला रिटर्न प्रकार फ़ंक्शन बॉडी का हिस्सा नहीं है। –

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