2009-07-30 13 views
8

संभव डुप्लिकेट:
What are the differences between Generics in C# and Java… and Templates in C++?सी # जेनरिक सी ++ टेम्पलेट्स की तुलना में

क्या सी ++ टेम्पलेट्स की तुलना में सी # जेनरिक के बीच मतभेद रहे हैं? मैं समझता हूं कि वे बिल्कुल एक ही समस्या का समाधान नहीं करते हैं, तो दोनों के पेशेवरों और विपक्ष क्या हैं?

+4

क्या संयोग है, यह आज के लिए मेरा ब्लॉग विषय है। http://blogs.msdn.com/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx –

+1

यह * सटीक डुप्लिकेट होने के लिए * मिला है। @ एरिक लिपर्ट: ओह, रोचक, इसे – jalf

उत्तर

16

आप विचार कर सकते हैं सी ++ टेम्पलेट्स एक जेनरिक प्रणाली के रूप में प्रच्छन्न एक व्याख्या की, कार्यात्मक प्रोग्रामिंग भाषा होने के लिए। यदि यह आपको डराता नहीं है, तो यह चाहिए :)

सी # जेनेरिक बहुत प्रतिबंधित हैं; आप एक प्रकार या प्रकार पर कक्षा को पैरामीटर कर सकते हैं, और विधियों में उन प्रकारों का उपयोग कर सकते हैं। तो, MSDN से एक उदाहरण लेते हैं, तो आप कर सकता है:

public class Stack<T> 
{ 
    T[] m_Items; 
    public void Push(T item) 
    {...} 
    public T Pop() 
    {...} 
} 

और अब आप, उस प्रकार के Stack<int> या Stack<SomeObject> और यह संग्रहीत करेंगे वस्तुओं घोषणा कर सकते हैं सुरक्षित रूप से (यानी, द्वारा में SomeOtherObject लगाने के बारे में कोई चिंतित गलती)।

आंतरिक रूप से, .NET रनटाइम इसे मौलिक प्रकारों जैसे कि int, और ऑब्जेक्ट प्रकारों के लिए एक संस्करण के रूप में विविधता में विशेषज्ञ करेगा। यह Stack<byte> के लिए Stack<SomeObject> की तुलना में बहुत छोटा होने के लिए प्रतिनिधित्व की अनुमति देता है, उदाहरण के लिए।

सी ++ टेम्पलेट्स एक ऐसी ही उपयोग करने की अनुमति:

template<typename T> 
class Stack 
{ 
    T *m_Items; 
    public void Push(const T &item) 
    {...} 
    public T Pop() 
    {...} 
}; 

यह पहली नज़र में समान दिखता है, लेकिन वहाँ कुछ महत्वपूर्ण अंतर है। सबसे पहले, प्रत्येक मौलिक प्रकार और सभी ऑब्जेक्ट प्रकारों के लिए एक संस्करण के बजाय, प्रत्येक प्रकार के लिए यह एक प्रकार है जिसे के विरुद्ध तत्काल किया गया है। यह बहुत सारे प्रकार हो सकता है!

अगला बड़ा अंतर (अधिकांश सी ++ कंपाइलर्स पर) इसे प्रत्येक अनुवाद इकाई में संकलित किया जाएगा जिसमें इसका उपयोग किया जाता है। इससे संकलन धीमा हो सकता है।

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

template<typename T> 
T min(const T &a, const T &b) { 
    return a > b ? b : a; 
} 

प्रकार टी स्वचालित रूप से उस संदर्भ द्वारा निर्धारित किया जाएगा जिसमें फ़ंक्शन का उपयोग किया जाता है।

इन गुणों का उपयोग आपकी स्वच्छता के खर्च पर, अच्छे सिरों पर किया जा सकता है। चूंकि एक सी ++ टेम्पलेट को प्रत्येक प्रकार के लिए पुन: संकलित किया जाता है, जिसका उपयोग इसके खिलाफ किया जाता है, और टेम्पलेट का कार्यान्वयन हमेशा कंपाइलर के लिए उपलब्ध होता है, सी ++ टेम्पलेट्स पर बहुत आक्रामक इनलाइनिंग कर सकता है। उसमें फ़ंक्शंस मानों का स्वचालित पता फ़ंक्शन में जोड़ें, और आप boost::lambda का उपयोग करके C++ में anonymous pseudo-functions बना सकते हैं। इस प्रकार, एक अभिव्यक्ति की तरह:

_1 + _2 + _3

एक गंभीरता से डरावना प्रकार है, जो एक ऑपरेटर है() जो अपने तर्कों कहते हैं के साथ एक वस्तु उत्पन्न करता है।

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

+0

* सी ++ के टेम्पलेट्स के लिए एक और दिलचस्प विशेषता यह है कि वे कक्षाओं के अलावा अन्य चीज़ों पर लागू हो सकते हैं * - क्या यह वही बात है जैसे सी # हमें कार्यों में जेनेरिक परिभाषित करने की अनुमति देता है (उदाहरण के लिए 'टी कुछफनक (टी इनपुट) {...} ')? – dotNET

3

http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88913.aspx

मोटे तौर पर, बहुत अधिक अंतर तथ्य यह है कि टेम्पलेट्स संकलन समय पर हल कर रहे हैं, और जेनरिक कार्यावधि में हल कर रहे हैं के साथ क्या करना है।

+2

पढ़ा जाएगा असल में यद्यपि जेनिक्स को रनटाइम पर प्रतिबिंबित किया जा सकता है (प्रतिबिंब के माध्यम से, किसी और चीज की तरह), संकलन समय पर बहुत कुछ पता लगाया जाता है। उदाहरण के लिए, जेआईटी 'सूची ' के बराबर एक सामान्य प्रकार-मिटा संस्करण का उपयोग करने के बजाय 'सूची ' का एक विशिष्ट कार्यान्वयन उत्पन्न करता है (यह जावा से अलग है)। –

+0

@ एरविकर: मुझे इसके बारे में बताएं। यही कारण है कि आप सामान्य पदोन्नति नहीं कर सकते हैं (यानी एक सूची सूची पर एक सूची को जोड़ना)। कार्यक्षमता सीएलआई में मौजूद है, लेकिन उन्होंने सी # (एक गलती, आईएमओ) में इसे लागू करने का विकल्प नहीं चुना है। –

1

यह blog entry from Eric Gunnerson काफी अच्छी तरह से इस विषय को शामिल किया गया।

सबसे बड़ा तत्काल अंतर यह है कि टेम्पलेट एक संकलित समय सुविधा है जबकि जेनरिक एक रनटाइम सुविधा है। स्टैक ओवरफ़्लो पर

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