2012-01-18 19 views
5

नोट: यह प्रश्न केवल छोटे से tinyxml से संबंधित है, हालांकि इस तरह के विवरण सहित अवधारणा को बेहतर तरीके से चित्रित करने में मदद मिल सकती है।किसी अन्य वर्ग/नामस्थान में फ़ंक्शन टेम्पलेट का विशेषज्ञता?

मैंने एक फ़ंक्शन टेम्पलेट लिखा है जो एक मूल एक्सएमएल नोड्स बच्चों के माध्यम से पुन: सक्रिय होगा, बच्चे तत्व के मूल्य को पुनः प्राप्त करेगा और फिर उस बच्चे तत्व तत्व को वेक्टर पर धक्का देगा।

'मान प्राप्त' भाग भी एक समारोह टेम्पलेट के रूप में लिखा है:

अर्थात

template <typename Type> 
Type getXmlCollectionItem(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent); 

पुनर्प्राप्ति भाग के लिए विशेषज्ञताओं, चाइल्ड तत्व मान, उदा के विभिन्न प्रकार के लौटने के लिए कर रहे हैं std :: स्ट्रिंग और अन्य कस्टम ऑब्जेक्ट्स।

अर्थात

template <> 
std::string getXmlCollectionItem<std::string>(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent); 

template <> 
MyObject getXmlCollectionItem<MyObject>(
    const char* elementName, TiXmlNode* child, TiXmlNode* parent); 

यह सब काम करता है पूरी तरह से अच्छी तरह से, लेकिन यह मुझे लगा कि यह एक साझा समारोह पुस्तकालय में है करने के लिए जब tinyxml फाइलों के साथ काम कर बहुत उपयोगी होगा।

प्रश्न: क्या एक नामस्थान में फ़ंक्शन टेम्पलेट घोषित करना संभव है उदा। namespace UtilityFunctions, जिसमें 'MyObject' जैसे विशिष्ट ऑब्जेक्ट प्रकारों का कोई ज्ञान नहीं है, और उसके बाद उस नाम टेम्पलेट के अन्य नामस्थानों में विशेषज्ञता टेम्पलेट की घोषणा और परिभाषित करें जिनके पास 'MyObject' जैसे विशिष्ट ऑब्जेक्ट प्रकारों का ज्ञान है?

मेरा झुकाव यह है कि यह संभव नहीं है, लेकिन एक सामान्य फ़ंक्शन टेम्पलेट रखने की अवधारणा मुझे उस कार्यक्षमता के करीब आने का एक वैकल्पिक तरीका होने के लिए पर्याप्त उपयोगी लगती है, जिसे मैं ढूंढ रहा हूं। ..

क्षमा करें यदि कोई भी शब्दावली गलत है या स्पष्टीकरण अस्पष्ट है। मैंने इस विषय के आस-पास बहुत सारे शोध किए हैं (उसी नामस्थान के भीतर कार्य करने वाले फ़ंक्शन टेम्पलेट विशेषज्ञता के बिंदु तक पहुंचने के लिए) लेकिन अभी तक कोई निश्चित उत्तर नहीं मिला है।

+1

आप फ़ंक्शन ओवरलोड का उपयोग कर सकते हैं ... वापसी बूल या त्रुटि कोड और संदर्भ द्वारा आउट पैरामीटर पास करें। – AJG85

+0

हां यह बहुत आसान होगा :) –

+0

[हर्ब सटर द्वारा यह आलेख] (http://www.gotw.ca/publications/mill17.htm) फ़ंक्शन विशेषज्ञता पर आपको प्रभावित कर सकता है ;-) – AJG85

उत्तर

3

यह एक में नाम स्थान एक टेम्पलेट की विशेषज्ञता के एक और नाम स्थान में परिभाषित (के बाद से है कि कि टेम्पलेट की विशेषज्ञता नहीं होगा, एक और नाम स्थान में परिभाषित किया जा रहा यह एक अलग टेम्पलेट होगा) लिखने के लिए संभव नहीं है।

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

तो यहाँ तुम क्या ऐसा नहीं कर सकते है:

namespace A { namespace B { 
    template <typename T> int foo(T) {throw 1;} 
}} 

template <> int A::B::foo(int) {throw 0;} 

आप http://www.comeaucomputing.com/tryitout/

"ComeauTest.c", line 5: error: the initial explicit specialization of function 
      "A::B::foo(T) [with T=int]" must be declared in the namespace 
      containing the template 
    template <> int A::B::foo(int) {throw 0;} 
         ^

यहाँ पर ऊपर के लिए अच्छा त्रुटि संदेश देख सकते हैं कि तुम क्या कर सकते हैं:

namespace A { namespace B { 
    template <typename T> int foo(T) {throw 1;} 
}} 

namespace A { namespace B { 
    template <> int foo(int) {throw 0;} 
}} 

क्या कोई कारण है कि यह एक समस्या होगी?

इसके अलावा, यदि आप उस ऑब्जेक्ट से जुड़े फ़ंक्शन में काम को प्रतिनिधि करते हैं जो आप पढ़ रहे हैं (या तो सदस्य या नि: शुल्क फ़ंक्शन), तो आप एडीएल के माध्यम से उस फ़ंक्शन पर निर्भर हो सकते हैं और कॉल कर सकते हैं। मतलब है कि आप उपर्युक्त जैसी विशेषताओं की मात्रा को कम करने में सक्षम होना चाहिए।

namespace A { namespace B { 
    template <typename T> int bar(T t) {return 0;} 
    template <typename T> int foo(T t) {return bar(t);} 
}} 

namespace C { 
    struct Bah {}; 
    int bar(Bah&) {return 1;} 
} 


int main(int argc,char** argv) 
{ 
    C::Bah bah; 

    std::cout << A::B::foo(0) << std::endl; 
    std::cout << A::B::foo(bah) << std::endl; 
} 

संपादित एक उदाहरण

+0

+1 बहुत अच्छा, एक एसओ सी ++ समुदाय पर गर्मजोशी से स्वागत है :) –

1

प्वाइंट यहाँ "है एक टेम्पलेट के लिए हर घोषणा, एक ही नाम स्थान में रखा जाना चाहिए किसी अन्य की तरह ही बार-बार घोषणाओं को जोड़ने के लिए:

यहाँ उदाहरण है नामित इकाई "

घोषणा/विभिन्न नामस्थान में इसे परिभाषित करना मान्य नहीं है, अधिक जानकारी के लिए कृपयामें 12 वें बिंदु से गुज़रें

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