क्या यह टेम्पलेट के साथ इनलाइन कीवर्ड का उपयोग करने का कोई मतलब है?


119

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


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

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

जवाबों:


96

यह अप्रासंगिक नहीं है। और नहीं, प्रत्येक फ़ंक्शन टेम्पलेट inlineडिफ़ॉल्ट रूप से नहीं है। मानक स्पष्ट विशेषज्ञता में इसके बारे में भी स्पष्ट है ([temp.expl.spec])

निम्नलिखित है:

a.cc

#include "tpl.h"

b.cc

#include "tpl.h"

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

#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यदि आप इसका मतलब लिखते हैं और बस संगत होना चाहिए। यह आपको इस बारे में कम सोचने देता है कि क्या सिर्फ इसलिए नहीं कि आप कर सकते हैं। (अंगूठे का यह नियम वन्देवोर्डे / जोसुटिस के सी ++ टेम्पलेट: द कम्प्लीट गाइड ) के अनुरूप है ।


2
कोई लिख सकता था, सच। लेकिन यह अधूरापन नहीं है, भले ही यह ऐसा प्रतीत होता है। वन्देवोर्डे और जोसटिस भी सी ++ टेम्प्लेट्स
सेबस्टियन मच

43
स्पष्ट विशेषज्ञता कोई खाका नहीं है।
पिल्ला

2
@ डीडीएमजी: फिर भी लुकअप पर एक पूर्ण विशेषज्ञता पर एक सामान्य कार्य पसंद किया जाता है, इसलिए यदि वे टेम्पलेट नहीं हैं, और न ही टेम्पलेट, तो वे क्या हैं?
सेबेस्टियन मच

13
यह उत्तर गलत है। टेम्पलेट का एक स्पष्ट विशेषज्ञता एक फ़ंक्शन है, टेम्पलेट नहीं। वह फ़ंक्शन inlineकेवल इसलिए नहीं बन जाता है क्योंकि जो टेम्पलेट विशेष था, वह चिह्नित है inline। तो inlineटेम्पलेट पर पूरी तरह अप्रासंगिक है। चाहे वह फ़ंक्शन inlineकिसी टेम्पलेट स्पेशलाइज़ेशन के माध्यम से उत्पन्न हो या न हो, इससे कोई लेना-देना नहीं है (और इस बात के बेहतर उत्तर हैं कि इसका उपयोग कब करें inline)। नीचे @Puppy का उत्तर सही है, यह एक नहीं है। inlineएक टेम्पलेट पर जोड़ना अप्रासंगिक है, और clang-tidyवास्तव में इसे हटा देगा।
gnzlbg

6
इसके अलावा, उदाहरण सिर्फ सामान्य कार्यों के लिए ODR मुद्दों को दिखाता है (वहाँ व्यवहार का खाका से कोई लेना देना नहीं है)। दिखा रहा है कि प्रयास करने के लिए inlineअप्रासंगिक नहीं हो रहा है, उदाहरण के लिए स्पष्ट रूप विशेषज्ञता के मामले को कवर करना चाहिए template<> void f<>(int) {} बिनाinline कीवर्ड। लेकिन फिर भी inlineटेम्प्लेट पर स्पेसिफिक को बदलने से कोई फर्क नहीं पड़ता है, क्योंकि आप टेम्प्लेट को चिन्हित करते हैं inlineया नहीं, अप्रासंगिक है।
gnzlbg

34

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


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

16
@phresnel: लेकिन टेम्प्लेट में एक ही शब्दार्थ है जैसे inline-मार्क किए गए फ़ंक्शंस (यानी, कई समान परिभाषाएँ लिंकर को पास की जा सकती हैं, जो एक का चयन करेगी)। यह, inlining नहीं, inlineकीवर्ड का वास्तविक कार्य है ।
बेन वोइग्ट

2
@BenVoigt: मुझे ODR के अर्थ के बारे में पता है inline। हो सकता है कि नीचे दिए गए (या ऊपर, चुने हुए छंटाई के आधार पर) मेरे उत्तर पर एक नज़र हो। गैर-विशिष्ट टेम्पलेट्स के लिए, आप निश्चित रूप से सही हैं, लेकिन यह औपचारिक रूप से समान नहीं है।
सेबेस्टियन मच

3
@ डीडएमजी: सी ++ में कोई आवश्यकता नहीं है कि एक हेडर फ़ाइल में एक फ़ंक्शन टेम्पलेट लागू किया जाना चाहिए; इसे कहीं भी लागू किया जा सकता है। इसे प्रतिबिंबित करने के लिए, मैं यह टैग करने की सिफारिश करता हूं inlineकि इनलाइन क्या होना चाहिए। यह आमतौर पर कोई फर्क नहीं पड़ता है, लेकिन मानक में, वे समान नहीं हैं, और वे सभी इनलाइन नहीं हैं। मैं यह कहते हुए आपके रुख को स्वीकार करता हूं कि "यह अप्रासंगिक है", लेकिन मानक के अनुसार, सभी टेम्पलेट इनलाइन नहीं हैं, केवल आपके लिए C ++ - उपयोगकर्ता के रूप में वे जैसे ही दिखाई देते हैं।
सेबेस्टियन मच

7
स्वीकार किए जाते हैं जवाब है कि स्पष्ट विशेषज्ञता एक टेम्पलेट नहीं है पर आपकी टिप्पणी (जो स्पष्ट है के बाद तो बेशक कहा जा रहा है, ....) शायद इस पृष्ठ पर सबसे उपयोगी बात है। क्या आप इसे अपने उत्तर में भी जोड़ेंगे?
काइल स्ट्रैंड

6

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

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

मार्शल क्लाइन मुझे यहाँ से बेहतर यह समझाता है कि मैं कर सकता हूँ।


@ Xeo: यह मामला नहीं हुआ करता था। यहां देखें: gcc.gnu.org/oniltocs/gcc-4.0.4/gcc/… मेरा मानना ​​है कि यह हाल ही में बदल गया है, इसीलिए मैं पिछले तनाव में बात कर रहा था।
घटक 10

2
@ Xeo: क्या आप मुझे द स्टैंडर्ड के उस हिस्से की ओर इशारा कर सकते हैं जिसमें कहा गया है कि फंक्शन टेम्पलेट हमेशा इनलाइन होते हैं? क्योंकि, वे नहीं हैं।
सेबेस्टियन मच

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

@Component 10 आपको क्यों लगता है कि यह गोल संकलन मुद्दा पाने का खराब तरीका है
कपिल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.