2009-07-10 33 views
36

के लिए अनिर्धारित संदर्भ त्रुटि यह पिछले डेढ़ घंटे से मुझे पागल कर रही है। मुझे पता है कि यह एक छोटी सी बात है लेकिन क्या गलत नहीं है (तथ्य यह है कि शुक्रवार दोपहर बारिश होती है, ज़ाहिर है, मदद नहीं करता है)।टेम्पलेट विधि

मैं निम्नलिखित वर्ग है कि एक फ़ाइल से पढ़ने कॉन्फ़िगरेशन पैरामीटर का आयोजन करेगा और मुझे उन्हें अपने कार्यक्रम से भी एक्सेस करने देगा परिभाषित किया है:

class VAConfig { 
    friend std::ostream& operator<<(std::ostream& lhs, const VAConfig& rhs); 

private: 
    VAConfig(); 
    static std::string  configFilename; 
    static VAConfig*  pConfigInstance; 
    static TiXmlDocument* pXmlDoc; 
    std::map<std::string, std::string> valueHash; 

public: 
    static VAConfig* getInstance(); 
    static void setConfigFileName(std::string& filename) { configFilename = filename; } 
    virtual ~VAConfig(); 

    void readParameterSet(std::string parameterGroupName); 
    template<typename T> T readParameter(const std::string parameterName); 
    template<typename T> T convert(const std::string& value); 
}; 

जहां विधि convert()

template <typename T> 
T VAConfig::convert(const std::string& value) 
{ 
    T t; 
    std::istringstream iss(value, std::istringstream::in); 
    iss >> t; 
    return t; 
} 
रूप VAConfig.cpp में परिभाषित किया गया है

सभी काफी सरल। लेकिन जब मैं अपने मुख्य

int y = parameters->convert<int>("5"); 

का उपयोग कर कार्यक्रम से परीक्षण मैं एक undefined reference to 'int VAConfig::convert<int>...' संकलन त्रुटि मिलती है। readParameter() के लिए डितो।

बहुत सारे टेम्पलेट ट्यूटोरियल देखे लेकिन इसे समझ में नहीं आया। कोई विचार?

+2

डेढ़ घंटे इतना बुरा नहीं है ... उसने मुझे कल 3 के लिए मार डाला। –

उत्तर

55

वाली टेम्प्लेट कोड कार्यान्वयन एक .cpp फ़ाइल में कभी नहीं होना चाहिए: आपके संकलक उन्हें एक ही समय में देखने के लिए के रूप में यह कोड है कि उन्हें कॉल (जब तक आप explicit instantiation का उपयोग टेम्प्लेटेड वस्तु कोड उत्पन्न करने के लिए देखता है, लेकिन तब भी .cpp है उपयोग करने के लिए गलत फ़ाइल प्रकार)।

आपको जो भी करना है, उसे हेडर फ़ाइल या कार्यान्वयन को VAConfig.t.hpp, और फिर #include "VAConfig.t.hpp" पर ले जाएं, जब भी आप किसी टेम्पलेट किए गए सदस्य फ़ंक्शंस का उपयोग करते हैं।

+0

धन्यवाद सेठ और डोमिनिक, मैंने कार्यान्वयन को teh हेडर फ़ाइल में ले जाया और यह काम किया। मैंने कभी भी इस ट्यूटोरियल में वर्णित इस पहलू को नहीं देखा। तो, कंपाइलर को कार्यान्वयन को देखने की आवश्यकता क्यों होती है, वैसे ही यह उन्हें कॉल करने वाले कोड को देखता है, यानी इस संबंध में टेम्पलेटेड फ्यूशनशन अद्वितीय क्या बनाता है? – recipriversexclusion

+2

कंपाइलर को पूरी टेम्पलेट परिभाषा उपलब्ध होने पर उपलब्ध होने की आवश्यकता होती है - ताकि यह टेम्पलेट पैरामीटर को प्रतिस्थापित कर सके और इसका मूल्यांकन कर सके। यदि आपका कंपाइलर इसका समर्थन करता है, तो आप अपने टेम्पलेट को "बाहरी" के रूप में घोषित कर सकते हैं और अतिरिक्त लिंक-टाइम काम की लागत पर इसे किसी भी अन्य सदस्य के रूप में उपयोग कर सकते हैं। जीसीसी इसे एक विस्तार के रूप में समर्थन करता है। यह सी ++ 0 एक्स मानक का हिस्सा बनने जा रहा है। – greyfade

+0

टेम्पलेट्स को दूर रखने के लिए तकनीकें हैं, अर्थात्, टेम्पलेट विशेषज्ञता घोषित करना। -1 "कभी नहीं होना चाहिए" –

9

यदि आप हेडर फ़ाइल में टेम्पलेटेड विधियों (कन्वर्ट और रीड पैरामीटर) के कार्यान्वयन को स्थानांतरित करते हैं, तो इसे काम करना चाहिए।

कंपाइलर को उन बिंदुओं पर टेम्पलेट किए गए कार्यों के कार्यान्वयन तक पहुंच होनी चाहिए जहां वे तत्काल हैं।

5

एक टेम्पलेट विधि केवल एक ... टेम्पलेट विधि के लिए है। टेम्पलेट तर्कों को भरना होगा जहां विधि "तत्काल" है।

टेम्पलेट विधि की घोषणा के साथ सामग्री वाला एक कंपाइलर बनाना संभव होना चाहिए, और 'टेम्पलेट संकलन' चरण टेम्पलेट विधि के सभी आवश्यक उदाहरणों को संकलित करना संभव है।

यह माइक्रोसॉफ्ट के वीसी के मामले में नहीं है। मैंने यूनिक्स पर मामला होने के बारे में एक कॉलेग्यू म्यूटर सुना है, हालांकि।

अधिकांश कंपाइलर अनुरोध पर टेम्पलेट विधि को तुरंत चालू करते हैं, जहां उनका उपयोग स्रोत कोड में किया जाता है। विधि को तुरंत चालू करने के लिए, कंपाइलर को टेम्पलेट फ़ंक्शन बॉडी को 'देखना' चाहिए। यही कारण है कि शरीर को अक्सर हेडर फ़ाइल में रखा जाता है, या उदा। एक .h.cpp फ़ाइल, जिसे तब .h फ़ाइल की अंतिम पंक्ति के रूप में शामिल किया जाता है।

+0

जो आप वर्णन कर रहे हैं वह एक "बाहरी टेम्पलेट" है। इसे सी ++ मानक के अगले संस्करण में शामिल किया गया है और इसे लंबे समय तक (विस्तार के रूप में) जीसीसी द्वारा समर्थित किया गया है। विज़ुअल सी ++ को अगली रिलीज के वर्तमान बीटा में इसका समर्थन करना चाहिए। – greyfade

+0

@ ग्रेफेड: धन्यवाद! – xtofl

+0

.h.cpp या .hpp? – Naveen

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