2011-11-30 9 views
16

कभी कभी यह एक अधूरी प्रकार के साथ एक मानक कंटेनर का दृष्टांत को एक पुनरावर्ती संरचना प्राप्त करने के लिए उपयोगी होता है:क्या मानक कंटेनर टेम्पलेट अपूर्ण प्रकारों के साथ तत्काल हो सकते हैं?

struct multi_tree_node { // Does work in most implementations 
    std::vector<multi_tree_node> child; 
}; 

struct trie_node { // Does not work in most implementations 
    std::map< char, trie_node > next; 
}; 

इसका कारण यह है कंटेनर प्रकार value_type या सदस्य कार्यों कि पारित के सदस्यों की जरूरत नहीं है या किसी value_type लौट काम करने के लिए जाता है मूल्य से वस्तुओं। मानक अपूर्ण टेम्पलेट तर्कों के बारे में बहुत कुछ नहीं कहता है, लेकिन सी ++ 11 §17.6.4.8 [lib.res.on.functions], "अन्य कार्यों पर आवश्यकताएं" के तहत एक बिट है:

विशेष रूप से, प्रभाव निम्न मामलों में अपरिभाषित हैं: ... यदि टेम्पलेट घटक को तत्काल करने पर टेम्पलेट तर्क के रूप में अपूर्ण प्रकार (3.9) का उपयोग किया जाता है, तब तक विशेष रूप से उस घटक के लिए अनुमति नहीं दी जाती है।

क्या इससे उपर्युक्त संरचनाएं अवैध होती हैं, भले ही तत्काल ब्लॉक दायरे में न हों? क्या यह "मानक लाइब्रेरी टेम्पलेट घटकों को चालू करने के लिए प्रयुक्त प्रकारों पर संचालन" के तहत आता है ((17.6.4.8)? या एक लाइब्रेरी कार्यान्वयन टेम्पलेट इंस्टॉलेशन के लिए वर्जित है जो अपूर्ण प्रकारों के लिए असफल हो सकता है जब सभी विशेष रूप से आवश्यक तत्काल आवश्यकताएं सफल होती हैं?

संपादित करें: के बाद से ही कार्यों फोन और ब्लॉक दायरे में उन लोगों के लिए अन्य कार्यों का दृष्टांत, सीमित "प्रकार पर कार्रवाई ..." हो सकता है हस्ताक्षर और सदस्य की सामग्री की तुलना में एक सख्त आवश्यकता के सदस्य कार्यों की सामग्री को धारण करने के लिए प्रतीत होता है कक्षा परिभाषाएं आखिरकार, को multi_tree_node के साथ टाइप पूरा होने तक निश्चित रूप से यह समझ में नहीं आता है। और यह std::unique_ptr तक फैला हुआ है जो ब्लॉक अपर में उपयोग किए जाने पर भी एक अपूर्ण प्रकार तर्क, का स्पष्ट रूप से समर्थन करता है।

संपादित करें 2:trie_node उदाहरण का परीक्षण करने के लिए परेशान न करने के लिए मुझे सही काम करता है - और मैंने पहले भी इसकी कोशिश की है। यह the article में टूटने का उदाहरण है जो @Ise से जुड़ा हुआ है। हालांकि, लेख यह मानने के लिए लगता है कि "ऐसा कुछ भी काम नहीं कर सकता है," समाधान मेरे लिए आसान लगता है - std::map की आंतरिक tree_node कक्षा एक गैर-सदस्य टेम्पलेट होना चाहिए, न कि सदस्य गैर-टेम्पलेट वर्ग।

वैसे भी, यह आलेख डिजाइन इरादे को अच्छी तरह से स्थापित करता है, इसलिए मुझे लगता है कि "कार्यों पर आवश्यकताओं" के उपशीर्षक के तहत होने के बारे में मेरा नाइटपिक केवल यही है।

+1

मुझे आपके द्वारा पोस्ट किए गए कोड में कोई अपूर्ण प्रकार नहीं दिख रहा है? –

+1

@ जॉन डीबलिंग: 'trie_node'' अगले' को परिभाषित करते समय अपूर्ण है। –

+1

@ जॉन डीबलिंग एक वर्ग के अपने दायरे के अंदर, यह अपूर्ण है। – Potatoswatter

उत्तर

4

व्यक्तिगत रूप से, मैं शब्दों instantiating 17.6.4.8/2 में एक छोटे से अस्पष्ट है, लेकिन this article, के अनुसार मानक की मंशा मानक कंटेनरों का इस्तेमाल किया पुनरावर्ती डेटा प्रकार की अनुमति नहीं लगता है लग रहा है।

एक संबंधित नोट पर, VC2005 class C { std::deque<C> x; }; के लिए एक त्रुटि जारी करता है, जबकि यह class C { std::vector<C> x; }; ...
संकलित हालांकि, मेरी समझ में, इस प्रतिबंध सिर्फ मानक कंटेनर के कार्यान्वयन की स्वतंत्रता के विस्तार के लिए है। तो जैसा कि Kerrek एस.बी. उल्लेख किया है, वहाँ कंटेनर जो पुनरावर्ती डेटा संरचना की अनुमति देते हैं हो सकता है, और Boost.Container इस सुविधा प्रदान करने के लिए लगता है।

10

यहाँ एक व्याख्या पर मेरे प्रयास है:

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

इसलिए, इस तरह के निर्माण सहित कार्यान्वयन को रोकने के लिए, मानक बस इतना कहता है कि आपको केवल पूर्ण प्रकार का उपयोग करना होगा। दूसरे शब्दों में, तथ्य यह है कि अधिकांश कंटेनरों में केवल मूल्य प्रकार के संदर्भ या पॉइंटर्स होते हैं, मानक आवश्यकता के बजाय कार्यान्वयन विवरण होता है।

बस इस स्पष्ट करने के लिए: यदि आप अपने खुद वर्ग टेम्पलेट को परिभाषित है, यह इस तरह से यह डिजाइन करने के लिए है कि यह स्पष्ट रूप से अधूरा प्रकार का समर्थन करता पूरी तरह से संभव है। मानक से एक उदाहरण std::unique_ptr है, जो अपूर्ण प्रकार पैरामीटर T[] (या यहां तक ​​कि void) से पूरी तरह से खुश है।

+0

+1 महान उदाहरण है, लेकिन मैं कुछ ab initio standardese व्याख्या के लिए प्रतीक्षा करने जा रहा हूं ... मेरा कोड निश्चित रूप से उद्धृत आवश्यकता का उल्लंघन करता है, लेकिन सवाल का दूसरा भाग यह है कि आवश्यकता फ़ंक्शन/ब्लॉक स्कोप के बाहर लागू होती है या नहीं। (चूंकि केवल फ़ंक्शन अन्य कार्यों को कॉल और तत्काल कर सकते हैं, इसलिए यह हस्ताक्षर और सदस्य वर्ग परिभाषाओं की सामग्री के मुकाबले सदस्य कार्यों की सामग्री को एक अलग मानक पर रखेगा।) – Potatoswatter

+0

"छोटा वेक्टर" एक महान उदाहरण नहीं है; मानक द्वारा अनुकूलन की अनुमति नहीं है। –

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