2010-09-20 13 views
37

एक टेम्पलेट वर्ग के कार्यान्वयन और घोषणा को एक ही शीर्षलेख फ़ाइल में क्यों होना चाहिए? क्या आप में से कोई इसे उदाहरण के द्वारा समझा सकता है?एक टेम्पलेट वर्ग के कार्यान्वयन और घोषणा को एक ही शीर्षलेख फ़ाइल में क्यों होना चाहिए?

+7

उन्हें एक ही संकलन इकाई के भीतर दिखाई देना होगा।यदि वे दोनों – Anycorn

+2

शामिल हैं तो वे अलग-अलग फाइलों में हो सकते हैं, वास्तव में यह दो फाइलों में घोषणा और कार्यान्वयन को विभाजित करने के लिए असामान्य नहीं है। हेडर में आमतौर पर कार्यान्वयन फ़ाइल शामिल होगी। – MSalters

+0

@MSalters: टेम्पलेट कक्षाओं के साथ समस्याग्रस्त कौन सा है, यह सवाल यही है। काश मैं टिप्पणियों को कम कर सकता हूं। –

उत्तर

24

टेम्पलेट के प्रत्येक तत्कालता के लिए कोड उत्पन्न करने के लिए कंपाइलर को संपूर्ण टेम्पलेट परिभाषा (केवल हस्ताक्षर नहीं) तक पहुंच की आवश्यकता है, इसलिए आपको कार्यों की परिभाषाओं को अपने शीर्षलेख में स्थानांतरित करने की आवश्यकता है।

अधिक जानकारी के लिए The Inclusion Model के बारे में पढ़ें।

+1

नहीं, आप नहीं करते। आप प्रत्येक टीयू में मैन्युअल रूप से परिभाषा लिख ​​सकते हैं, लेकिन निश्चित रूप से हेडर कन्वेंशन आपको ऐसे बकवास से बचने में मदद के लिए डिज़ाइन किया गया है। :) –

+0

@LightnessRacesinOrbit क्या मैं पूछ सकता हूं कि टीयू क्या है? – athos

+0

@athos http://en.wikipedia.org/wiki/Translation_unit_%28programming%29 –

6

कक्षा टेम्पलेट की परिभाषा और उसके सदस्य कार्यों के कार्यान्वयन को प्रत्येक स्थान पर दिखाई देना चाहिए जो इसे एक अलग प्रकार के साथ त्वरित करता है। यानी myTemplate<int> को तुरंत चालू करने के लिए आपको myTemplate की पूर्ण परिभाषा और कार्यान्वयन को देखने की आवश्यकता है।

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

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

यानी अगर आपने myTemplate<int> और myTemplate<std::string> के रूप में परिभाषित extern तो आप उन्हें ठीक उपयोग कर सकते हैं, लेकिन अगर myTemplate<double>extern परिभाषित नहीं है तो आप उपयोग नहीं कर सकते कि कार्यान्वयन के बिना है।

4

सामान्य वर्ग के मामले में, घोषणा संकलन के लिए पर्याप्त है, और इसी परिभाषा से जुड़ी होगी।

टेम्पलेट्स के मामले में, कंपाइलर को भी परिभाषा की आवश्यकता है कोड उत्पन्न करें।

अंतर C++ FAQ में बेहतर समझाया गया है।

4

उन्हें नहीं करना है।

तत्कालता (जहां इसका उपयोग किया जाता है) पर टेम्पलेट परिभाषा को देखने के लिए आवश्यक है ताकि संकलक इस बिंदु पर टेम्पलेट से वर्ग/फ़ंक्शन प्राप्त कर सके।

हालांकि यह बहुत टेम्पलेट कक्षाओं के लिए दो हेडर फाइल उपयोग आम है:

// foo_fwd.hpp 
template <typename T, typename U> struct Foo; 

// foo.hpp 
#include "foo_fwd.hpp" 

template <typename T, typename U> struct Foo { typedef std::pair<T,U> type; }; 

यह जो लोग पूर्ण टेम्पलेट परिभाषा की जरूरत नहीं है कुछ हद तक एक लाइटर हेडर को शामिल करने के लिए अनुमति देता है, उदाहरण के लिए:

//is_foo.hpp 
#include <boost/mpl/bool.hpp> 
#include "foo_fwd.hpp" 

template <typename Z> 
struct is_foo: boost::mpl::false_ {}; 

template <typename T, typename U> 
struct is_foo< Foo<T,U> >: boost::mpl::true_ {}; 

जो संकलन-समय को थोड़ा बढ़ा सकता है।

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