2013-01-04 18 views
5

मैं a.hक्यों स्पष्ट टेम्पलेट इन्स्टेन्शियशन की स्थिति बात

#include <iostream> 

template<bool b> 
class A { 
public: 
    void print(std::ostream& out); 
}; 

में एक टेम्पलेट वर्ग A घोषित और

#include "a.h" 

template<bool b> 
void A<b>::print(std::ostream& out) { 
    out << "A" << b; 
} 

template class A<true>; 
template class A<false>; 

(true के लिए स्पष्ट instatiation और false के साथ) a.cpp में प्रिंट विधि को परिभाषित करता है कहो main.cpp में एक मुख्य मुख्य कार्यक्रम

हो सकता है

उपरोक्त छोटी परियोजना सिर्फ ठीक है।

प्रश्न: यदि मैं print विधि (a.cpp में) की परिभाषा के ऊपर स्पष्ट instantiations शब्दों में कहें, कोड सामान्य undefined reference to A<true>::print(...) त्रुटि के साथ अब और संकलन नहीं है।

#include "a.h" 

template class A<true>; 
template class A<false>; 

template<bool b> 
void A<b>::print(std::ostream& out) { 
    out << "A" << b; 
} 

ऐसा क्यों है?

संपादित: Makefile संकलित करने के लिए

main : main.o a.o 
    g++ main.o a.o -o main 

main.o : main.cpp 
    g++ -c main.cpp 

a.o : a.cpp 
    g++ -c a.cpp 
+1

वीएस2012 पर भी काम करता है। – billz

+0

मैंने किया और मैंने आदेश बदल दिया क्योंकि देजन ने – billz

+1

@jogojapan - +1 का उल्लेख किया था। मैंने अपनी टिप्पणी हटा दी है जिसमें कहा गया है कि यह clang32 और gcc48 के साथ संकलित है। यह किसी भी कंपाइलर के साथ ठीक से संकलित था और किसी भी आदेश के साथ यदि तीन फाइलों की सामग्री को एक फ़ाइल में काट दिया गया था और चिपकाया गया था - जैसे मैंने शुरुआत में अपने परीक्षण के लिए किया था। डिज़न ने मेकफ़ाइल पोस्ट करने के बाद, मैं किसी भी संस्करण के क्लैंग और जीसीसी के साथ त्रुटि पुन: उत्पन्न करने में सक्षम था। –

उत्तर

8

मुझे नहीं लगता कि यह अच्छा क्यों है प्राकृतिक स्पष्टीकरण क्यों ऐसा है। जाहिर है, संकलक सदस्य फ़ंक्शन की परिभाषा को देख सकता है भले ही यह स्पष्ट तत्काल – के बाद प्रदान किया गया हो क्योंकि यह एक ही फ़ाइल में स्थित है।

हालांकि, कंपेलरों को इसकी आवश्यकता नहीं है; यह तथ्य स्पष्ट रूप से मानक से मना किया है:

(§14.7.2/9) एक स्पष्ट इन्स्टेन्शियशन परिभाषा यह है कि नाम एक वर्ग टेम्पलेट विशेषज्ञता स्पष्ट रूप से वर्ग टेम्पलेट विशेषज्ञता को दर्शाता है और केवल उन सदस्यों में से एक स्पष्ट इन्स्टेन्शियशन परिभाषा है जिसे तत्कालता के बिंदु पर परिभाषित किया गया है।

मैं इस के लिए कारणों में निम्न शामिल लगता है:

  • हो सकती है कई अलग स्पष्ट बाद में अनुवाद इकाई में सदस्य कार्यों में से कुछ के लिए विशेषज्ञता; यह प्रोग्रामर के हित में भी समझ में आता है, इस बारे में एक स्पष्ट नियम है कि इनमें से कौन सा तत्काल होगा;

  • जब कोई टेम्पलेट तत्काल तत्काल है, तो तत्कालता के बिंदु से पहले परिभाषित विशेषज्ञता केवल ध्यान में रखी जाती है; तो नियम निहित और स्पष्ट तत्काल के लिए समान है।

1
template class A<true>; 
template class A<false>; 

इसी कारण कारण है कि यह आम तौर पर उम्मीद है कि टेम्पलेट कोड हैडर अपने आप में परिभाषित किया गया है। स्पष्ट तत्काल निष्पादन करने के लिए, आप (कंपाइलर) को में सक्षम होने की आवश्यकता है टेम्पलेट वर्ग की संपूर्ण परिभाषा, जो आपके main.cpp से संभव नहीं है।

हालांकि a.cpp कक्षा (यहां प्रिंट विधि) की सभी परिभाषाओं तक पहुंच है, इसलिए स्पष्ट तत्काल कार्य वहां काम करता है।

+0

मुझे यकीन नहीं है कि मैं आपका जवाब समझता हूं। मेरा भ्रम 'a.cpp' के भीतर बयानों के पुनर्मूल्यांकन के साथ है। –

+0

@ DejanJovanović: आह मेरी गलतफहमी, तो यह एक कंपाइलर चीज़ की तरह दिखता है, यह वीएस -2010 पर काम करता है –

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