एक.CPP फ़ाइल में C++ टेम्पलेट फ़ंक्शन परिभाषा संग्रहीत करना




templates (7)

मेरे पास कुछ टेम्पलेट कोड है जो मैं शीर्षलेख में इनलाइन की बजाय एक सीपीपी फ़ाइल में संग्रहीत करना पसंद करूंगा। मुझे पता है कि यह तब तक किया जा सकता है जब तक आपको पता चले कि कौन से टेम्पलेट प्रकारों का उपयोग किया जाएगा। उदाहरण के लिए:

एच फाइल

class foo
{
public:
    template <typename T>
    void do(const T& t);
};

.cpp फ़ाइल

template <typename T>
void foo::do(const T& t)
{
    // Do something with t
}

template void foo::do<int>(const int&);
template void foo::do<std::string>(const std::string&);

पिछली दो पंक्तियों पर ध्यान दें - foo :: do टेम्पलेट फ़ंक्शन केवल इनट्स और std :: स्ट्रिंग्स के साथ उपयोग किया जाता है, इसलिए उन परिभाषाओं का अर्थ है कि ऐप लिंक करेगा।

मेरा सवाल है - क्या यह एक बुरा हैक है या यह अन्य कंपाइलर्स / लिंकर्स के साथ काम करेगा? मैं फिलहाल वीएस 2008 के साथ इस कोड का उपयोग कर रहा हूं लेकिन अन्य वातावरणों को बंदरगाह करना चाहता हूं।


अद्यतन के लिए समय! एक इनलाइन (.inl, या शायद कोई अन्य) फ़ाइल बनाएं और बस अपनी सभी परिभाषाओं को कॉपी करें। प्रत्येक फ़ंक्शन के ऊपर टेम्पलेट को जोड़ना सुनिश्चित करें ( template <typename T, ...> )। अब इनलाइन फ़ाइल में हेडर फ़ाइल को शामिल करने के बजाय आप विपरीत करते हैं। अपनी कक्षा ( #include "file.inl" ) की घोषणा के बाद इनलाइन फ़ाइल शामिल करें।

मुझे सच में नहीं पता कि किसी ने इसका उल्लेख क्यों नहीं किया है। मुझे कोई तत्काल कमी नहीं दिख रही है।


आपका उदाहरण सही है लेकिन बहुत पोर्टेबल नहीं है। एक हल्का क्लीनर सिंटैक्स भी है जिसका उपयोग किया जा सकता है (जैसा कि @ नेमस्पेस-एसआईडी द्वारा इंगित किया गया है)।

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

एक वैकल्पिक दृष्टिकोण आपके पास जो कुछ है उसमें थोड़ी भिन्नता है: एक तीसरी फ़ाइल जोड़ें जो टेम्पलेट कार्यान्वयन / तत्काल फ़ाइल है।

foo.h फ़ाइल

// Standard header file guards omitted

template <typename T>
class foo
{
public:
    void bar(const T& t);
};

foo.cpp फ़ाइल

// Always include your headers
#include "foo.h"

template <typename T>
void foo::bar(const T& t)
{
    // Do something with t
}

foo-impl.cpp फ़ाइल

// Yes, we include the .cpp file
#include "foo.cpp"
template class foo<int>;

एक चेतावनी यह है कि आपको foo-impl.cpp बजाय foo-impl.cpp संकलित करने के लिए कंपाइलर को बताने की आवश्यकता है क्योंकि उत्तरार्द्ध कुछ भी नहीं करता है।

बेशक, आप तीसरे फ़ाइल में कई कार्यान्वयन कर सकते हैं या आपके द्वारा उपयोग किए जाने वाले प्रत्येक प्रकार के लिए कई कार्यान्वयन फाइलें हो सकती हैं।

अन्य उपयोगों के लिए टेम्पलेट श्रेणी साझा करते समय यह अधिक लचीलापन सक्षम बनाता है।

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


आपके द्वारा वर्णित समस्या को हेडर में टेम्पलेट को परिभाषित करके या ऊपर वर्णित दृष्टिकोण के माध्यम से हल किया जा सकता है।

मैं सी ++ एफएक्यू लाइट से निम्नलिखित बिंदुओं को पढ़ने की सलाह देता हूं:

वे इन (और अन्य) टेम्पलेट मुद्दों के बारे में बहुत अधिक जानकारी देते हैं।


इस पृष्ठ पर अन्य लोगों के लिए यह सोचकर कि स्पष्ट टेम्पलेट विशेषज्ञता (या कम से कम VS2008 में) के लिए सही वाक्यविन्यास (जैसा मैंने किया) है, यह निम्नलिखित है ...

आपकी .h फ़ाइल में ...

template<typename T>
class foo
{
public:
    void bar(const T &t);
};

और आपकी .cpp फ़ाइल में

template <class T>
void foo<T>::bar(const T &t)
{ }

// Explicit template instantiation
template class foo<int>;

यह कोड अच्छी तरह से गठित है। आपको केवल ध्यान देना होगा कि टेम्पलेट की परिभाषा तत्काल बिंदु पर दिखाई दे रही है। मानक उद्धृत करने के लिए, § 14.7.2.4:

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


यह ठीक काम करना चाहिए हर जगह टेम्पलेट समर्थित हैं। स्पष्ट टेम्पलेट तत्काल सी ++ मानक का हिस्सा है।


हां, यह विशेषज्ञता को तत्काल तत्काल करने का मानक तरीका है। जैसा कि आपने कहा है, आप इस टेम्पलेट को अन्य प्रकारों से तुरंत चालू नहीं कर सकते हैं।

संपादित करें: टिप्पणी के आधार पर सही।





templates