2011-06-15 19 views
9

मैंने हाल ही में this से पूछा कि डी में प्रकार कक्षाओं का अनुकरण कैसे करें और टेम्पलेट विशेषज्ञता का उपयोग करके ऐसा करने का एक तरीका सुझाया गया है।विभिन्न स्रोत फ़ाइल में डी टेम्पलेट विशेषज्ञता

मुझे पता चला कि डी एक अलग स्रोत फ़ाइल में टेम्पलेट विशेषज्ञता को पहचान नहीं पाया है। इसलिए मैं उस फ़ाइल में शामिल नहीं हो सकता था जिसमें फ़ाइल से शामिल नहीं है जहां जेनेरिक फ़ंक्शन परिभाषित किया गया है। उदाहरण के लिए, इस उदाहरण पर विचार करें:

//template.d 
import std.stdio; 
template Generic(A) { 
    void sayHello() { 
    writefln("Generic"); 
    } 
} 

void testTemplate(A)() { 
    Generic!A.sayHello(); 
} 


//specialization.d 
import std.stdio; 
import Template; 

template Generic(A:int) { 
    void sayHello() { 
     writefln("only for ints"); 
    } 
} 

void main() { 
    testTemplate!int(); 
} 

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

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

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

+0

यह उन कारणों के लिए बड़े पैमाने पर अनुमति नहीं है जिनमें अवांछित फ़ंक्शन अपहरण से बचने के लिए उदाहरण शामिल है, उदाहरण के लिए यदि 'जेनेरिक' निजी होगा तो 'template.d' किसी भी अन्य टेम्पलेट को ओवरराइड नहीं करना चाहेंगे जो मनमानी सामान कर सकता है –

+0

" उपनाम "लिखता है टेम्पलेट। जेनेरिक जेनेरिक "specialization.d में मदद करता है? यह फ़ंक्शन अपहरण को लागू करने का तरीका है http://d-programming-language.org/hijack.html –

उत्तर

5

मुझे लगता है कि मैं इस प्रश्न का उचित उत्तर दे सकता हूं। सं।

आप जो करने का प्रयास कर रहे हैं वह template.d की कार्यक्षमता को हाइजैक कर रहा है (यह भी फ़ाइल फ़ाइल और आयात टेम्पलेट से मेल खाना चाहिए, कुछ ऑपरेटिंग सिस्टम महत्वपूर्ण हैं)। पर विचार करें:

// specialization.d 
import std.stdio; 
import template; 
import helper; 

void main() { 
    testTemplate!int(); 
    getUserData(); 
} 

बिल्कुल सही सही:

// template.d 
... 

// spezialisation.d 
import std.stdio; 
import template; 

void main() { 
    testTemplate!int(); 
} 

अब कोई कोड अद्यतन करता है? अच्छी तरह से अंदर सहायक:

// helper.d 
getUserData() { ... } 


template Generic(A:int) { 
    A placeholder; //... 
} 

अब आप सिर्फ एक आयात से और वास्तव में इस संकलन के रूप में यह sayHello कॉल नहीं कर सकते विफल हो जाएगा specialization.d के व्यवहार को बदल दिया है। इस हाईजैक रोकथाम में इसके मुद्दे हैं। उदाहरण के लिए आपके पास एक ऐसा फ़ंक्शन हो सकता है जो एक रेंज लेता है, लेकिन आपकी लाइब्रेरी का उपभोक्ता एक सरणी पास नहीं कर सकता है जब तक कि आपकी लाइब्रेरी std.array आयात नहीं करती है, क्योंकि यह एक सरणी "रूपांतरित" होती है।

मेरे पास आपकी समस्या के लिए कोई समाधान नहीं है।

मीकल की टिप्पणी highjacking का दूसरा रूप है, जहां specialization.d getUserData

// specialization.d 
import std.stdio; 
import template; 
import helper; 

alias helper.getUserData getUserData; 

string getUserData(int num) { ... } 

void main() { 
    testTemplate!int(); 
    getUserData(); 
} 
0

IIRC highjack करने की कोशिश की कहने के लिए एक समाधान प्रदान करता है; डी में एक सामान्य मामला के रूप में, विभिन्न फ़ाइलों में प्रतीकों को अधिभारित नहीं किया जा सकता है क्योंकि प्रतीक के पूर्ण नाम में मॉड्यूल नाम (फ़ाइल नाम) उन्हें अलग-अलग प्रतीक बनाते हैं। यदि 2 या अधिक प्रतीकों का एक ही अयोग्य नाम है और 2 या अधिक फ़ाइलों से हैं, तो उस अयोग्य प्रतीक का उपयोग करने का प्रयास करने से संकलन त्रुटि हो जाएगी।

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