2010-08-12 18 views
6

C++ में यह एक funcction कि एक समारोह स्थानीय प्रकार लगता है ठीक है:टेम्पलेट स्थानीय प्रकार क्यों काम नहीं कर सकते हैं?

template<typename T> void Foo(const T& t) { } 

int main() { 
    struct S { } s; 
    Foo(s); // Line 5: error: no matching function for call to 'Foo(main()::S&)' 
} 

14.3.1 paragraph 2 in the c++ standard.

एक प्रकार:

int main() { 
    struct S { static void M(const S& s) { } }; 
    S s; 
    S::M(s); 
} 

लेकिन ठीक नहीं एक है कि करता है टेम्पलेट के लिए बिना किसी लिंक के [...] टेम्पलेट प्रकार-पैरामीटर

के लिए टेम्पलेट-तर्क के रूप में उपयोग नहीं किया जाएगा

सी ++ क्यों अस्वीकार करता है?


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


पेज। कृपया न केवल "thats not allowed because the standard says it's not"

+5

कोई अच्छा कारण नहीं है, और सी ++ 0x इस प्रतिबंध को हटा देगा (लेकिन पीएस में से जुड़ा कोई नहीं; मुझे अभी भी कोई सुराग नहीं है कि इसकी अनुमति क्यों नहीं है)। –

+0

@ माइक; संक्षिप्त एवं सटीक! – BCS

उत्तर

3

मुझे लगता है कि ऐसा इसलिए है क्योंकि इसे फ़ंक्शन के दायरे में प्रभावी ढंग से तत्काल चालू करने की आवश्यकता होगी, क्योंकि ऐसा ही है जहां ऐसे प्रकार दिखाई दे रहे हैं। हालांकि, साथ ही, टेम्पलेट इंस्टॉलेशन को कार्य करना चाहिए जैसे कि वे उस दायरे में हैं जिसमें टेम्पलेट परिभाषित किया गया है। मुझे यकीन है कि किसी भी तरह से निपटना संभव है, लेकिन यदि मैं सही हूं तो मानक निकाय ने संकलन लेखकों पर उस बोझ को न डालने का फैसला किया।

इसी तरह का निर्णय vector<vector<int>> मानक प्रति अमान्य वाक्यविन्यास था; यह पता लगाने के लिए कि कंपाइलर लेजर और पार्सर चरणों के बीच निर्माण के लिए कुछ बातचीत की आवश्यकता है। हालांकि, यह बदल रहा है, क्योंकि सी ++ 0 एक्स मानकों के लोक ने पाया कि सभी कंपाइलर इसे सैक त्रुटि संदेशों को उत्सर्जित करने के लिए वैसे भी इसका पता लगा रहे हैं।

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

+1

"सोमदेय" जैसे ही सी ++ 0x को अनुमोदित किया जाएगा, जब तक कि वे अपना मन बदल नहीं लेते। अंतिम मसौदा इस प्रतिबंध को हटा देता है। –

+0

मैं कल्पना कर सकता हूं कि एक कंपाइलर आर्किटेक्चर जहां इसे कार्यान्वित करना मुश्किल होगा, लेकिन मैं उन लोगों के बारे में भी सोच सकता हूं जहां यह मुफ्त में होगा। – BCS

7

मुझे विश्वास है कि Foo<T> के दो तत्कालताओं के साथ वास्तव में पूरी तरह से अलग-अलग चीजों का अर्थ है, क्योंकि T दोनों के लिए समान नहीं था। टेम्पलेट्स (सीफ्रंट समेत) के कुछ प्रारंभिक कार्यान्वयन ने टेम्पलेट इंस्टॉलेशन के एक भंडार का उपयोग किया, इसलिए संकलक स्वचालित रूप से एक आवश्यक प्रकार पर एक टेम्पलेट को तुरंत चालू कर सकता है जब/अगर यह पाया गया कि उस प्रकार का तत्कालता पहले से ही भंडार में नहीं था।

स्थानीय प्रकार के साथ यह काम करने के लिए, संग्रह केवल उस प्रकार को संग्रहीत करने में सक्षम नहीं होगा जिस पर टेम्पलेट को तत्काल बनाया गया था, लेकिन इसके बजाय इसे किसी प्रकार के लिए "पथ" बनाने जैसा कुछ करना होगा तात्कालिकता हालांकि यह संभव है, मुझे लगता है कि इसे छोटे (यदि कोई हो) वास्तविक लाभ के लिए बहुत अधिक काम के रूप में देखा गया था।

तब से, नियमों में काफी बदलाव आया है कि संकलक को पहले से ही कुछ ऐसा करने की आवश्यकता है जो अलग-अलग स्थानों (टीयूएस समेत) पर उसी प्रकार के तत्काल, ढूंढने (और कोलेसिंग) के बारे में है, ताकि foo<int> के दो तत्काल (उदाहरण के लिए) ओडीआर का उल्लंघन नहीं करते हैं।उस प्राप्ति के आधार पर, प्रतिबंध (सी ++ 0x के वर्तमान मसौदे) में अवरुद्ध हो गया है (आप अभी भी एक स्थानीय प्रकार पर एक टेम्पलेट वर्ग को चालू नहीं कर सकते हैं, लेकिन आप टेम्पलेट फ़ंक्शन पर स्थानीय प्रकार का पैरामीटर के रूप में उपयोग कर सकते हैं) ।

+0

संक्षेप में, यह कंपाइलर के लिए और अधिक काम करता था? – BCS

+0

@ बीबीसीएस: हालांकि यह शायद सच भी है, यह इतना * नहीं है कि यह कंपाइलर के लिए अधिक काम करता था, क्योंकि यह है कि 1) अधिकांश अतिरिक्त काम अब अन्य कारणों से किया जा रहा है, और 2) संकलन सी ++ अब इतना जटिल है कि लोग अभी भी अधिक जटिलता जोड़ने के लिए अधिक इच्छुक हैं, जब तक कि यह बहुत कठोर न हो। –

+0

§14.3.1 [temp.arg.type] में क्लास टेम्पलेट में स्थानीय प्रकारों को पारित करने के कई उदाहरण हैं। – Potatoswatter

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