2012-05-10 7 views
82

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


संपादित करें: मैं दोनों उत्तरों को स्वीकार करना चाहता हूं, लेकिन यह संभव नहीं है। मुद्दा मैं phresnel को स्वीकार कर रहा हूँ बंद करने के लिए की जवाब है, क्योंकि यह सबसे अधिक वोट प्राप्त हुआ है और वह औपचारिक रूप से सही है, लेकिन जैसा कि मैंने टिप्पणी में उल्लेख किया है मैं पिल्ला पर विचार 'भी सही लोगों के रूप में और घटक 10 के जवाब , विभिन्न बिंदुओं से।

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

उत्तर

65

यह अप्रासंगिक नहीं है। और नहीं, डिफ़ॉल्ट रूप से प्रत्येक फ़ंक्शन टेम्पलेट inline नहीं है।

a.cc

#include "tpl.h" 

b.cc: मानक स्पष्ट विशेषज्ञता ([temp.expl.spec])

है निम्नलिखित में इसके बारे में भी स्पष्ट है

#include "tpl.h" 

tpl।ज (स्पष्ट विशेषज्ञता से लिया गया):

#ifndef TPL_H 
#define TPL_H 
template<class T> void f(T) {} 
template<class T> inline T g(T) {} 

template<> inline void f<>(int) {} // OK: inline 
template<> int g<>(int) {} // error: not inline 
#endif 

इस संकलित करें, एट देखा:

g++ a.cc b.cc 
/tmp/ccfWLeDX.o: In function `int g<int>(int)': 
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)' 
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here 
collect2: ld returned 1 exit status 

inline बताते हुए नहीं जब स्पष्ट इन्स्टेन्शियशन कर भी समस्याएं हो सकती हैं।

तो सारांश में: गैर पूरी तरह से विशेष समारोह टेम्पलेट्स, अर्थात जो कि कम से कम एक अज्ञात प्रकार ले लिए, आप inline छोड़ सकते हैं, और त्रुटियों का सामना करना नहीं है, लेकिन फिर भी वे inline नहीं हैं। पूर्ण विशेषज्ञता के लिए, यानी जो केवल ज्ञात प्रकारों का उपयोग करते हैं, आप इसे छोड़ नहीं सकते हैं।

अंगूठे का प्रस्तावित नियम: inline लिखें यदि आप इसका मतलब रखते हैं और केवल सुसंगत हैं। इससे आपको लगता है कि आप कर सकते हैं या नहीं, इस बारे में कम सोचते हैं। (अंगूठे का यह नियम Vandevoorde's/Josuttis's C++ Template: The Complete Guide के अनुरूप है)।

+0

स्पष्ट विशेषज्ञता के लिए यह सच है - वे सादे कार्यों की तरह हैं। लेकिन यहां -> 'टेम्पलेट इनलाइन टी जी (टी) {}' इनलाइन की आवश्यकता नहीं है और आप 'टेम्पलेट टी जी (टी) {} ' – doc

+1

लिखा होगा, कोई लिखा होगा, सच। लेकिन यह असभ्यता का अर्थ नहीं है, भले ही ऐसा लगता है। वंदेवोर्डे और जोसुटिस यह भी बताते हैं कि _C++ टेम्पलेट्स में: पूर्ण मार्गदर्शिका_ –

+0

थोड़ा कमजोर बयान है कि टेम्पलेट्स में कई परिभाषाएं हो सकती हैं (3.2/5) -> http://stackoverflow.com/a/10211420/205955 मैं सहमत हूं कि यह इस बात का तात्पर्य नहीं है कि वे औपचारिक रूप से इनलाइन हैं। हालांकि, यह सब अभ्यास में इस पर आता है। इसलिए, दोनों उत्तरों विभिन्न दृष्टिकोणों से सही हैं। – doc

21

यह अप्रासंगिक है। सभी टेम्पलेट्स पहले से ही inline हैं - उल्लेख नहीं है कि 2012 तक, inline कीवर्ड का एकमात्र उपयोग ओडीआर उल्लंघनों के बारे में बताते हुए कंपाइलर्स को रोकना है। आप बिल्कुल सही हैं- आपके वर्तमान पीढ़ी के कंपाइलर को पता चलेगा कि इसके बारे में क्या कहना है और शायद अनुवाद इकाइयों के बीच भी ऐसा कर सकता है।

+5

मानक यह नहीं बताता है कि सभी टेम्पलेट इनलाइन हैं। –

+10

@phresnel: लेकिन टेम्पलेट्स में समान अर्थशास्त्र है जो 'इनलाइन'-चिह्नित फ़ंक्शंस (यानी, एकाधिक समकक्ष परिभाषाएं लिंकर को पास की जा सकती हैं, जो एक का चयन करेगी)। वह, इनलाइन नहीं, 'इनलाइन' कीवर्ड का वास्तविक कार्य है। –

+0

@BenVoigt: मुझे 'इनलाइन' के ओडीआर अर्थ के बारे में पता है। शायद नीचे दिए गए मेरे उत्तर (या ऊपर, चुने हुए सॉर्टिंग के आधार पर) पर एक झलक है। गैर-विशिष्ट टेम्पलेट्स के लिए, आप निश्चित रूप से सही हैं, लेकिन यह औपचारिक रूप से समान नहीं है। –

1

जैसा कि आपने सुझाव दिया था, inline कंपाइलर के लिए एक संकेत है और कुछ भी नहीं। यह इनलाइनों को अनदेखा करना चुन सकता है, वास्तव में, इनलाइन फ़ंक्शंस इनलाइन चिह्नित नहीं किया जा सकता है।

टेम्पलेट्स के साथ inline का उपयोग करने के लिए टेम्पलेट्स के साथ एक (खराब) तरीका होता है जो प्रत्येक संकलन इकाई एक ही टेम्पलेटेड क्लास के लिए एक अलग वस्तु बनाती है जो लिंक समय पर डुप्लिकेशंस के मुद्दों का कारण बनती है। inline (मुझे लगता है) का उपयोग करके नाम मैंगलिंग अलग-अलग काम करता है जो लिंक समय पर नाम के दौर में आता है लेकिन बड़े पैमाने पर फूले हुए कोड की कीमत पर।  

मार्शल क्लाइन explains it here मैं जितना कर सकता हूं उससे बेहतर।

+0

@Xeo: यह मामला नहीं था। यहां देखें: http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Template-Instantiation.html# टेम्पलेट- इंस्टेंटेशन मुझे लगता है कि हाल ही में बदल गया है, इसलिए मैं पिछले काल में बात कर रहा था। –

+1

@Xeo: क्या आप मुझे मानक के हिस्से में इंगित कर सकते हैं जिसमें कहा गया है कि फ़ंक्शन टेम्पलेट हमेशा इनलाइन होते हैं? क्योंकि, वे नहीं हैं। –

+0

@phresnel: दिलचस्प, मैं कसम खाता हूं कि मैंने इसे मानक में पढ़ा है। हो सकता है कि मैंने इसे इस तथ्य से मिश्रित किया कि फ़ंक्शन टेम्पलेट्स को ओडीआर ('§14.5.5.1 पी 7 और पी 8') से छूट दी गई है। मेरा बुरा, मैंने गलत टिप्पणी हटा दी। – Xeo

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