2009-11-19 7 views
5

कहते हैं कि तुम सरल टेम्पलेट कार्य हो ही ज फ़ाइल में प्रकार विशिष्ट विशेषज्ञता के साथ (सादगी के लिए नहीं वर्ग के सदस्य) की सुविधा देता है ...क्या कंपाइलर टेम्पलेट विशेषज्ञता के मामले में इनलाइन को अनदेखा करने की अनुमति है?

template <class TYPE> 
void some_function(TYPE& val) 
{ 
    // some generic implementation 
} 

template <> 
inline void some_function<int>(int& val) 
{ 
    // some int specific implementation 
} 

जब तक आप स्पष्ट रूप से आपके inline विशेषज्ञता के लिए संकलक प्रत्यक्ष (inline कीवर्ड) यदि आप .h फ़ाइल को एक से अधिक बार शामिल करते हैं तो आपको लिंकिंग त्रुटि मिल जाएगी (कम से कम मैं दृश्य सी ++ 2008 में करता हूं)।
हम सभी जानते हैं कि inline संकलक के लिए सिर्फ एक सुझाव है, जो इसे अनदेखा कर सकता है। इस विशेष मामले में संकलक को इस सुझाव को अनदेखा करने और लिंकर को विफल होने की अनुमति है?

+0

यह उन अंधेरे सी ++ कोनों में से एक है। –

+2

इसे पढ़ें: http://stackoverflow.com/questions/1759300/c-when-should-i-write-the-keyword-inline-for-a-function-method/1759575#1759575 –

उत्तर

5

आप अक्सर उल्लिखित "अनदेखा इनलाइन" संभावना के अर्थ को गलत समझ रहे हैं।

किसी भी कंपाइलर को फ़ंक्शन घोषणा में उपयोग किए गए inline विनिर्देशक को अनदेखा करने की अनुमति नहीं है और इसके विनिर्देशक एक परिभाषा नियम (ओडीआर) के संबंध में हैं।

जब कोई कहता है कि कंपाइलर को "इनलाइन को अनदेखा" करने की अनुमति है, तो इसका मतलब केवल यह है कि संकलक को वास्तव में पर कॉल करने के लिए कॉल करने की आवश्यकता नहीं है। इनलाइन फ़ंक्शन में एक सामान्य (गैर-रेखांकित) फ़ंक्शन कॉल उत्पन्न करने के लिए "इनलाइन अनदेखा करें" का अर्थ है।

किसी भी मामले में, भले ही कंपाइलर ने हमेशा एक इनलाइन फ़ंक्शन (यानी हमेशा "इनलाइन को अनदेखा" करने के लिए सामान्य कॉल जेनरेट करने का निर्णय लिया), फिर भी इसे ओडीआर के प्रयोजनों के लिए फ़ंक्शन का उपयोग करने की आवश्यकता है। संकलक कैसे करने जा रहा है यह संकलक की समस्या है। आपको इसके बारे में चिंता करने की ज़रूरत नहीं है।

आपके मूल उदाहरण में आपको कोई लिंकर त्रुटियां नहीं मिलनी चाहिए।

+0

धन्यवाद आंद्रे, यही मेरा सवाल था। – BostonLogan

7

आप inline का उपयोग नहीं करते हैं, तो एक ही समारोह कई .obj फाइलों में extern संबंध है, जो लिंकर डुप्लिकेट प्रतीक त्रुटि फेंक कारणों के साथ संकलित हो जाता है।

इस संकलक वास्तव में, संकलित अपने समारोह इनलाइन है कि क्या के बाद से यह यह एक static समारोह के रूप में एक ही इलाज है और प्रत्येक कार्यान्वयन प्रत्येक संकलन इकाई के लिए निजी बना सकता से स्वतंत्र है। हालांकि, आप इस उद्देश्य के लिए static का उपयोग नहीं कर सकते हैं क्योंकि इसका मतलब सदस्य कार्यों पर कुछ और है, इसलिए inline आपकी एकमात्र पसंद है।

+0

धन्यवाद ग्रेग। क्या मैं यह मानने के लिए सही हूं कि इनलाइन दोहरी उद्देश्य कीवर्ड है? और टेम्पलेट विशेषज्ञता के मामले में बाहरी लिंकेज दबाया जाता है जबकि फ़ंक्शन अभी भी इनलाइन हो सकता है या नहीं? – BostonLogan

+0

'इनलाइन' फ़ंक्शंस में अभी भी बाहरी संबंध (3.5/3) है। ओडीआर के पास प्रत्येक टीयू में उनकी परिभाषा की अनुमति देने के लिए एक विशेष मामला है। –

+0

@ बोस्टन लॉगन: अगर लोग "इनलाइन" जैसे वाक्यांशों का उपयोग करना बंद कर देते हैं तो यह वास्तव में मदद करेगा। ;-) यदि किसी फ़ंक्शन में इनलाइन कीवर्ड होता है (या स्पष्ट रूप से तत्काल तत्काल टेम्पलेट्स और वर्ग परिभाषा में परिभाषित सदस्य फ़ंक्शंस की तरह इनलाइन है), तो सी ++ शब्दों में यह "इनलाइन" है। चाहे कंपाइलर फ़ंक्शन में किसी विशेष कॉल को रेखांकित करता है, फ़ंक्शन की प्रॉपर्टी नहीं है, क्योंकि यह संकलक तक है (शायद संकेत के रूप में इनलाइन स्थिति लेना), और दूसरी बात यह है कि यह कुछ कॉलों के बारे में सच हो सकती है लेकिन दूसरों को नहीं। –

0

मेरा मानना ​​है कि आप स्पष्ट रूप से विधि को बाहरी रूप से घोषित कर सकते हैं और फिर विशेषज्ञता को .cpp में डाल सकते हैं। मैंने जीसीसी के साथ पिछले जीवन में कुछ ऐसा करने की कोशिश की है, लेकिन मुझे यह पता नहीं चला कि यह कैसे काम करता है। MSDN Magazine has an article on this जो मदद कर सकता है।

0

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

किसी भी फ़ंक्शन के लिए इनलाइन का उपयोग करना, केवल एक संकेत है, लेकिन यदि फ़ंक्शन छोटा है (किसी भी फ़ंक्शन के लिए) या यदि आप इसे हेडर में रखना चाहते हैं तो आप इसे लागू करना चाहेंगे। यहाँ इनलाइन बिना एक उदाहरण है:

हैडर फ़ाइल:

template<class TYPE> 
void some_function(TYPE& val) { 
    // some generic implementation 
} 

template<> 
void some_function<int>(int& val); 

कार्यान्वयन (सीपीपी) फ़ाइल:

template<> 
void some_function<int>(int& val) { 
    // some int specific implementation 
} 
1

इस मानक द्वारा परिभाषित किया गया है और संकलक इस संबंध में पूरी तरह से अनुपालन करता है, इसके दिखने से। जुड़ाव वह सब है जिसके बाद आप हैं। इनलाइन फ़ंक्शंस के रूप में लागू टेम्पलेट इंस्टॉलेशन में 'विशेष' लिंक होता है। वहाँ भी स्थिर (कीवर्ड) है, जो गुमनाम नामस्थान के पक्ष में पदावनत किया गया है:

void some_other_function(int& val) { 
    // some int specific implementation 
} 

वास्तव में:

namespace { 
    …declarations… 
} 

तो हाँ, इस विशेषज्ञता (अपने उदाहरण में) के रूप में ही संबंध है , संकलक विशेषज्ञता को रेखांकित करने के बारे में सोच सकता है, आपके उदाहरण में, कह रहा है कि वे मेल नहीं खाते हैं। तो यह वास्तव में इनलाइन (या अन्यथा) दोनों को लेबल करने का सबसे अच्छा अभ्यास है।

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