2017-01-28 13 views
39

कोड पर निम्नलिखित कोड क्यों काम करते हैं?मैं एक ही कक्षा के सदस्य वेक्टर की घोषणा कैसे कर सकता हूं?

struct A { 
    std::vector<A> subAs; 
}; 

ए एक अपूर्ण प्रकार है, है ना? अगर ए * एस का वेक्टर था तो मैं समझूंगा। लेकिन यहां मुझे समझ में नहीं आता कि यह कैसे काम करता है। यह एक पुनरावर्ती परिभाषा प्रतीत होता है।

+8

ठीक है, निम्नतम स्तर पर, यह एक "पुनरावर्ती परिभाषा" है या नहीं इस पर निर्भर करेगा कि 'std :: vector' वर्ग में स्वयं 'ए' प्रकार के उप-उपनिवेश शामिल हैं या नहीं। 'Std :: vector' के एक सामान्य कार्यान्वयन में 'ए' प्रकार का कोई प्रत्यक्ष उप-विषय नहीं है। 'Std :: vector' के एक सामान्य कार्यान्वयन में इसमें नियंत्रित अनुक्रम में केवल 'ए *' सूचक शामिल होगा।यह डेटा रिकर्सन को समाप्त करता है और अपूर्ण प्रकारों को तर्क के रूप में उपयोग करना संभव बनाता है। यहां एकमात्र सवाल यह है कि क्या भाषा विनिर्देश इसकी अनुमति देता है या इसकी आवश्यकता है। – AnT

+0

से संबंधित [वेक्टर के लिए टेम्पलेट पैरामीटर के रूप में अपूर्ण प्रकार का उपयोग कैसे किया जा सकता है?] (Http://stackoverflow.com/q/31345193/1708801) –

उत्तर

31

यह paperinto C++17 अपनाया गया था जो कुछ एसटीएल कंटेनर में अपूर्ण प्रकारों का उपयोग करने की अनुमति देता है। इससे पहले, यह अपरिभाषित व्यवहार था। कागज से उद्धृत करने के लिए:

Issaquah बैठक पर चर्चा के आधार पर हमने दृष्टिकोण के साथ आगे बढ़ने के लिए आम सहमति * हासिल की - "अपूर्ण प्रकार के कंटेनर", लेकिन std::vector, std::list को दायरा सीमित, और std::forward_list, पहले चरण के रूप में।

और मानक (जोर मेरा) में परिवर्तन के लिए के रूप में:

अपूर्ण प्रकार T जब vector instantiating इस्तेमाल किया जा सकता है, तो संभाजक संतुष्ट संभाजक-पूर्णता-आवश्यकताओं (17.6.3.5.1)। टी परिणामस्वरूप वेक्टर के विशेषज्ञता के किसी भी सदस्य से पहले पूरा हो जाएगा।

तो, वहाँ तुम्हारे पास है, अगर आप जगह में डिफ़ॉल्ट std::allocator<T> छोड़ जब std::vector<T, Allocator> instantiating, तो यह हमेशा एक अधूरी प्रकार T कागज के अनुसार के साथ काम करेंगे; अन्यथा, यह आपके ऑलोकेटर पर एक अपूर्ण प्रकार T के साथ तत्काल होने पर निर्भर करता है।


एक एक अधूरी प्रकार, सही है? अगर ए * एस का वेक्टर था तो मैं समझूंगा। लेकिन यहां मुझे समझ में नहीं आता कि यह कैसे काम करता है। यह एक पुनरावर्ती परिभाषा प्रतीत होता है।

वहां कोई रिकर्सन नहीं है।

class A{ 
    A* subAs; 
}; 

तकनीकी तौर पर, size अलावा, capacity और संभवतः allocator, std::vector केवल यह अपने संभाजक के माध्यम से प्रबंधन करता है A की एक गतिशील सरणी के लिए सूचक धारण करने के लिए की जरूरत है: एक अत्यंत सरलीकृत रूप में, यह के समान है। (और एक सूचक का आकार संकलन समय पर जाना जाता है।)

तो, एक क्रियान्वयन ऐसा दिखाई दे सकता है:

namespace std{ 

    template<typename T, typename Allocator = std::allocator<T>> 
    class vector{ 

     .... 

     std::size_t m_capacity; 
     std::size_t m_size; 
     Allocator m_allocator; 
     T* m_data; 
    }; 

} 
+5

मुझे लगता है कि http://stackoverflow.com/questions/6517231/ हैं-सी-रिकर्सिव-टाइप-डेफिनिशन-संभव-में-विशेष-कैन-आई-पुट-ए-वेक्टर अपडेट किया जाना चाहिए :) – kennytm

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

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