2012-01-23 11 views
5

मुझे एक अजीब समस्या है। विंडोज़ पर, विजुअल स्टूडियो 2010 के साथ और इंटेल कंपाइलर के साथ सब कुछ अपेक्षित के रूप में जुड़ा हुआ है। लेकिन जब मैं लिनक्स पर CLang 3.0 के साथ अपना कोड संकलित करने का प्रयास करता हूं, तो यह संकलित करता है (और यदि मैं केवल एक सीपीपी फ़ाइल का उपयोग करता हूं तो यह लिंक और रन भी करता है) लेकिन लिंक नहीं करता है।लिनक्स सी ++: एकाधिक फ़ाइलों में टेम्पलेट विशेषज्ञता का सही तरीके से उपयोग कैसे करें?

संदेश यह है कि टेम्पलेट instanciations का जिक्र करते हुए, कई प्रतीक परिभाषाएं हैं।

"फ़ाइल xyz":

template<class T> void myFunc(T in) { } 
template<> void myFunc<int>(int in) { } 
लिनक्स लिंकर मैं की तर्ज पर कुछ मिलेगा से

अब उदाहरण के लिए: एक हेडर फाइल कई संकलन इकाइयों के पार साझा में निम्नांकित दो पंक्तियों पर विचार एकाधिक "myFunc (int in)" की परिभाषा, जिसे पहले "कुछ फ़ाइल" में परिभाषित किया गया था।

लेकिन मैं इसे कैसे रोकूं? चूंकि यह विंडोज़ पर काम करता है, मुझे लगता है कि इसे किसी भी तरह लिनक्स पर भी काम करना चाहिए?

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

बाकी सब विफल रहता है मुझे लगता है मैं अभी भी एक "MakeAll.cpp" फाइल जो सिर्फ सभी सीपीपी देखते हैं शामिल हैं बना सकते हैं लगता है, लेकिन है कि मेरे पास एक वांछनीय समाधान की तरह ध्वनि नहीं है, तो ...

के लिए धन्यवाद आपकी सहायता!

+0

क्या आप # शामिल गार्ड का उपयोग कर रहे हैं? –

+1

@SteveC उपयोगकर्ता यह बता रहा है कि कोड संकलित करता है लेकिन लिंक नहीं करता है। शामिल गार्ड लिंक समय त्रुटियों के बजाय कंपाइलर त्रुटियों को ट्रिगर करेगा। –

उत्तर

8

मेरी समझ में, आप वास्तव में कई बार अपने टेम्पलेट विशेषज्ञता को परिभाषित कर रहे हैं, और इससे आपको विंडोज कंपाइलर्स के लिए भी त्रुटि मिलनी चाहिए।

अपने हेडर फाइल में आप एक समारोह को परिभाषित करने के लिए एक शरीर प्रदान करके कर रहे हैं:

template<> void myFunc<int>(int in) { } 

इस परिभाषा कई संकलन इकाइयों में मौजूद हैं और लिंकर चाहिए शिकायत करेंगे।

वही नियम साधारण गैर टेम्पलेट कार्यों के लिए के रूप में अपने टेम्पलेट विशेषज्ञता के लिए आवेदन: या तो inline का उपयोग करें या

template<> void myFunc<int>(int in); 
एक शीर्षक में

और

template<> void myFunc<int>(int in) 
{ 
    // ... 
} 
रख कर एक अलग घोषणा और परिभाषा का उपयोग

.cpp फ़ाइल में।

+0

यह विंडोज पर शिकायत नहीं करता है। मैं जितनी जल्दी हो सके इनलाइन चीज की कोशिश करूंगा;)। मुद्दा यह है कि मुझे स्थिर टेम्पलेट डेटा सदस्यों की आवश्यकता है (यह मेरा वर्तमान दृष्टिकोण है)। और वे एक ही मुद्दे के साथ आते हैं कि मैं उन्हें इनलाइन नहीं कर सकता ?! – thesaint

+0

यह उत्तर अधूरा है। Http://stackoverflow.com/questions/5453361/c-template-specialization-linker-error-multiple-definitions –

0

मेरे पास अभी मानक नहीं है, लेकिन मुझे लगता है कि विशेषज्ञता inline घोषित करनी होगी।

+0

मैं कोशिश करूँगा लेकिन मैं स्थिर टेम्पलेट डेटामैम्बर के बारे में क्या करूं ?! वे एक ही त्रुटि उत्पन्न करते हैं लेकिन मैं उन्हें इनलाइन नहीं कर सकता ... – thesaint

+1

@thesaint आपको एक पूर्ण अनुवाद इकाई में * पूर्ण speceializations * (यानी किसी भी टेम्पलेट तर्क से स्वतंत्र) के स्थिर डेटा सदस्यों की परिभाषाओं को स्थानांतरित करना होगा। बात यह है कि एक पूर्ण विशेषज्ञता टेम्पलेट नहीं है, और टेम्पलेट नहीं है यह टेम्पलेट नियमों द्वारा नहीं खेलता है। –

+0

मुद्दा यह है कि यह संभव नहीं है! क्योंकि उन्हें साझा हेडर में घोषित किया जाना है। आम तौर पर, आप प्रत्येक संकलन इकाई को निजी बनाने के लिए डेटा घोषणा के सामने "स्थैतिक" प्रीपेड कर सकते हैं, लेकिन यह टेम्पलेट डेटा के लिए काम नहीं करता है ?! और शायद यही वजह है कि एमएसवीसी लिंकर इन संघर्षों को अनदेखा करता है। क्योंकि अगर कोड में उन्हें छुटकारा पाने का कोई तरीका नहीं है, तो लिंकर सिर्फ मूर्खतापूर्ण काम करता है अगर यह चेतावनी के बजाए त्रुटि की रिपोर्ट करता है; कम से कम अगर कुछ भी नहीं है तो मैं इसके बारे में कर सकता हूं ?! – thesaint

3

टेम्पलेट्स को कंपाइलर द्वारा तत्काल किया जाता है, और यह सुनिश्चित करने के लिए संकलक जिम्मेदारी है कि उन्हें केवल एक बार परिभाषित किया जाता है।

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

इन कार्यों

template<> 
void f<int>(int x) 
{ } 

void f(int x) 
{ } 

बीच बहुत कम अंतर है, जब यह एक परिभाषा शासन करने के लिए आता है।

inline जोड़ना दोनों मामलों में मदद करता है।

+0

ठीक है, तो यह तब CLang 3 में एक बग है। हो सकता है कि आपके पास स्थैतिक टेम्पलेट डेटा सदस्यों का समाधान भी हो ?! वे एक ही परेशानी का कारण बनते हैं और मैं उन्हें इनलाइन नहीं कर सकता ... – thesaint

+0

मुझे लगता है कि क्लेंग सही है, लेकिन वास्तव में यह दूसरों को इसे काम करने के लिए वास्तव में एक त्रुटि नहीं है। :-) और मुझे नहीं लगता कि डेटा मैक्रोज़ के लिए एक समाधान है, आपके मैक्रोज़ को दो भागों में विभाजित करने के अलावा, हेडर के लिए एक और कार्यान्वयन के लिए एक। "एकाधिक परिभाषा टेम्पलेट विशेषज्ञता" पर शीर्ष दर्जन Google प्रविष्टियों में से –

+0

आपका उत्तर केवल यही बता रहा था कि क्यों! –

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