2008-11-10 5 views
18

मुझे पता है कि मूल सी ++ 0x मानक में export नामक एक सुविधा थी।सी ++ 0x मानक में निर्यात कीवर्ड के लिए सबसे अच्छा स्पष्टीकरण क्या है?

लेकिन मैं एक विवरण या इस सुविधा का विवरण नहीं मिल रहा। यह क्या करना चाहिए? इसके अलावा: कौन सा कंपाइलर इसका समर्थन कर रहा है? क्योंकि वे disaprove -

उत्तर

22

हालांकि मानक सी ++ की कोई आवश्यकता नहीं है, कुछ कंपेलरों की आवश्यकता है कि सभी फ़ंक्शन टेम्पलेट्स को प्रत्येक अनुवाद इकाई में उपलब्ध कराया जाना चाहिए। असल में, उन कंपाइलरों के लिए, टेम्पलेट कार्यों के निकायों को उपलब्ध कराया जाना चाहिए एक हेडर फ़ाइल में। दोहराने के लिए: इसका मतलब है कि उन कंपाइलर्स उन्हें गैर-हेडर फ़ाइलों जैसे .cpp फ़ाइलों में परिभाषित करने की अनुमति नहीं देंगे।स्पष्ट करने के लिए, C++ ese इसका मतलब है कि यह:

// ORIGINAL version of xyz.h 
template <typename T> 
struct xyz 
{ 
    xyz(); 
    ~xyz(); 
}; 

नहीं ctor की इन परिभाषाओं और dtors के साथ संतुष्ट हो जाएगा: क्योंकि यह का उपयोग कर

// ORIGINAL version of xyz.cpp 
#include "xyz.h" 

template <typename T> 
xyz<T>::xyz() {} 

template <typename T> 
xyz<T>::~xyz() {} 

:

// main.cpp 
#include "xyz.h" 

int main() 
{ 
    xyz<int> xyzint; 

    return 0; 
} 

एक त्रुटि उत्पन्न करेगा। उदाहरण के लिए, Comeau सी के साथ ++ आप प्राप्त करेंगे:

C:\export>como xyz.cpp main.cpp 
C++'ing xyz.cpp... 
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86 
Copyright 1988-2004 Comeau Computing. All rights reserved. 
MODE:non-strict warnings microsoft C++ 

C++'ing main.cpp... 
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86 
Copyright 1988-2004 Comeau Computing. All rights reserved. 
MODE:non-strict warnings microsoft C++ 

main.obj : error LNK2001: unresolved external symbol xyz<T1>::~xyz<int>() [with T1=int] 
main.obj : error LNK2019: unresolved external symbol xyz<T1>::xyz<int>() [with T1=int] referenced in function _main 
aout.exe : fatal error LNK1120: 2 unresolved externals 

ctor या dtor xyz.cpp भीतर का कोई उपयोग नहीं है क्योंकि, इसलिए, वहाँ कोई instantiations वहाँ से होने की जरूरत है। बेहतर या बदतर के लिए, इस तरह टेम्पलेट काम करते हैं।

xyz<int> के इस उदाहरण में xyz के तत्काल अनुरोध का स्पष्ट रूप से अनुरोध करना है। एक जानवर बल के प्रयास में, यह यह के अंत में इस पंक्ति जोड़कर xyz.cpp में जोड़ा जा सकता:

template xyz<int>; 

जो अनुरोध करता है कि (के सभी) instantiated जा xyz<int>। हालांकि यह गलत जगह पर है, क्योंकि इसका मतलब यह है कि हर बार एक नया xyz प्रकार लाया जाता है कि कार्यान्वयन फ़ाइल xyz.cpp को संशोधित किया जाना चाहिए। एक कम दखल तरीका है कि फ़ाइल से बचने के लिए एक और बनाने के लिए है:

// xyztir.cpp 
#include "xyz.cpp" // .cpp file!!!, not .h file!! 

template xyz<int>; 

यह अभी भी कुछ हद तक दर्दनाक है, क्योंकि यह अभी भी एक मैनुअल हस्तक्षेप हर एक नया xyz आगे लाया जाता है की आवश्यकता है। एक गैर-तुच्छ कार्यक्रम में यह एक अनुचित रखरखाव मांग हो सकती है।

बजाय, एक और तरीका यह दृष्टिकोण xyz.h के अंत में #include "xyz.cpp" के लिए है:

// xyz.h 

// ... previous content of xyz.h ... 

#include "xyz.cpp" 

आप निश्चित रूप से सचमुच करने के लिए ला सकता है (कट और पेस्ट करें) xyz.cpp की सामग्री xyz.h का अंत, इसलिए xyz.cpp से छुटकारा पा रहा है; यह फ़ाइल संगठन का एक प्रश्न है और अंत में प्रीप्रोकैसिंग के परिणाम समान होंगे, जिसमें सीटीओआर और डीटोर निकाय हेडर में होंगे, और इसलिए किसी भी संकलन अनुरोध में लाया गया है, क्योंकि यह संबंधित शीर्षलेख का उपयोग करेगा। किसी भी तरह से, इसका दुष्प्रभाव है कि अब हर टेम्पलेट आपकी हेडर फ़ाइल में है। यह संकलन धीमा कर सकता है, और इसके परिणामस्वरूप कोड ब्लोट हो सकता है। उत्तरार्द्ध तक पहुंचने का एक तरीका यह है कि प्रश्नों में प्रश्नों को घोषित करना है, इस मामले में सीटीओआर और डाटर, इनलाइन के रूप में, इसलिए आपको चल रहे उदाहरण में xyz.cpp को संशोधित करने की आवश्यकता होगी।

एक तरफ के रूप में, कुछ कंपाइलरों को यह भी आवश्यक है कि कुछ कार्यों को कक्षा के अंदर इनलाइन परिभाषित किया जाए, न कि एक के बाहर, इसलिए उपरोक्त सेटअप को उन कंपाइलरों के मामले में आगे tweaked करने की आवश्यकता होगी। ध्यान दें कि यह एक संकलक मुद्दा है, मानक सी ++ में से एक नहीं, इसलिए सभी कंपाइलरों को इसकी आवश्यकता नहीं है। उदाहरण के लिए, कॉमौ सी ++ नहीं करता है, न ही इसे चाहिए। हमारे वर्तमान सेटअप के विवरण के लिए http://www.comeaucomputing.com/4.0/docs/userman/ati.html देखें। संक्षेप में, कॉमौ सी ++ कई मॉडलों का समर्थन करता है, जिनमें से एक निर्यात कीवर्ड के इरादे (विस्तार के रूप में) के साथ-साथ निर्यात निर्यात का भी समर्थन करता है।

अंत में, ध्यान दें कि सी ++ निर्यात कीवर्ड मूल प्रश्न को कम करने के लिए है। हालांकि, वर्तमान में कॉमौ सी ++ एकमात्र कंपाइलर है जिसे निर्यात का समर्थन करने के लिए प्रचारित किया जा रहा है। कुछ विवरणों के लिए http://www.comeaucomputing.com/4.0/docs/userman/export.html और http://www.comeaucomputing.com/4.3.0/minor/win95+/43stuff.txt देखें। उम्मीद है कि अन्य कंपाइलर मानक सी ++ के अनुपालन तक पहुंचते हैं, यह स्थिति बदल जाएगी।उपरोक्त उदाहरण में, निर्यात का उपयोग कर मूल कोड है जो लिंकर त्रुटियों का उत्पादन करने के लिए लौट, और एक परिवर्तन करने का अर्थ है: xyz में

// xyz.h 

export 
// ... ORIGINAL contents of xyz.h ... 

ctor और dtor: निर्यात कीवर्ड के साथ xyz.h में टेम्पलेट घोषणा करते हैं। सीपीपी को #ycludeing xyz.h के आधार पर निर्यात किया जाएगा, जो यह पहले से ही करता है। इसलिए, इस मामले में आपको xyztir.cpp की आवश्यकता नहीं है, न ही xyz.cpp के अंत में तत्काल अनुरोध, और आपको ctor या dtor मैन्युअल रूप से xyz.h में लाया जाने की आवश्यकता नहीं है। पहले दिखाए गए कमांड लाइन के साथ, यह संभव है कि संकलक स्वचालित रूप से आपके लिए यह सब करे।

+1

नोट [ग्रेग रोजर्स का उत्तर] (http://stackoverflow.com/a/279617/481061) और वहां टिप्पणियां - 'निर्यात' कीवर्ड को मानक से हटा दिया गया था और शायद किसी अन्य कंपाइलर में कभी भी लागू नहीं किया जाएगा। –

6

इसके उपयोग

काफी कुछ compilers इसका समर्थन नहीं करते क्योंकि या तो यह बिल्कुल नई है या जीसीसी के मामले में है के लिए this स्पष्टीकरण देखें।

इस पोस्ट में कई compilers के लिए मानक समर्थन वर्णन करता है। Visual Studio support for new C/C++ standards?

+1

यह बहुत नया नहीं है, यह सी ++ 98 मानक में अन्य सुविधाओं की तरह 10 साल पुराना है! : डी यह और अधिक है कि इसे कार्यान्वित करने के लिए संकलक के एक नया स्वरूप की आवश्यकता है, और वे नहीं सोचते कि यह इसके लायक है। – KTC

+3

यह लिंकर को मुश्किल बनाता है, खासकर यदि आप लिंक चरण –

1

केवल compilers समर्थन है कि (मैं जानता हूँ कि जहाँ तक) इस समय निर्यात टेम्पलेट्स Comeau, एक कि बोर्लेन्ड सी ++ बिल्डर एक्स के साथ आया था, लेकिन नहीं वर्तमान सी ++ बिल्डर, और इंटेल (हैं कम से कम अनधिकृत रूप से, यदि आधिकारिक तौर पर नहीं, तो सुनिश्चित नहीं है)।

4

यह बस डाल करने के लिए:

export आप परिभाषा से घोषणा (। यानी हेडर) को अलग कर देता है (यानी कोड।) जब आप अपने टेम्पलेट वर्गों लिखें। यदि export आपके कंपाइलर द्वारा समर्थित नहीं है तो आपको घोषणा और परिभाषा को एक स्थान पर रखना होगा।

5

इस विषय के हर्ब सटर के उपचार के लिए here और here देखें।

मूल रूप से: निर्यात केवल one कंपाइलर में लागू किया गया है - और उस कार्यान्वयन में, निर्यात वास्तव में टेम्पलेट परिभाषा और घोषणा के बीच युग्मन को बढ़ाता है, जबकि निर्यात शुरू करने का एकमात्र बिंदु इस युग्मन को कम करना था।

है यही कारण है कि सबसे compilers परेशान नहीं है। मैंने सोचा होगा कि वे सी ++ 0x में भाषा से निर्यात को हटा देंगे, लेकिन मुझे नहीं लगता कि उन्होंने किया था। हो सकता है कि कुछ दिन निर्यात को लागू करने का एक अच्छा तरीका होगा जिसका उद्देश्य उपयोग किया जाए।

+1

में बहुत से चालाक पूरे प्रोग्राम अनुकूलन करना चाहते हैं तो हर्ब सटर एक माइक्रोसॉफ्ट कर्मचारी है। उन्होंने सी ++ 0x से निर्यात को हटाने की कोशिश की है, और असफल रहा। तो उनकी राय कुछ पक्षपातपूर्ण हो सकती है। प्रकटीकरण: मैंने आईएसओ को अपना प्रस्ताव दिया। – MSalters

+0

क्यों टिप्पणी करने के लिए देखभाल? सब कुछ जो मैं इस पर खोदने में सक्षम हूं, इसका तात्पर्य है कि यह सुविधा एक मृत मुद्दा है, चाहे वह मानक में बनी रहे या नहीं। –

+1

एक एमएस कर्मचारी होने वाले सटर के पास इसके साथ कुछ लेना देना नहीं है, वह सोचता है कि निर्यात काम नहीं कर रहा है, इसलिए सोचें कि इसे हटाया जाना चाहिए। – KTC

4

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

Comeau यह पहली बार शुरू की, के बारे में 5 साल पहले IIRC। मैंने पहली बीटा रिलीज पर काफी अच्छा काम किया। यहां तक ​​कि> एक < 2 की तरह testcases>>> बी < 2 का उपयोग कर एक < 1 का उपयोग बी < 1 का उपयोग कर का उपयोग करते हुए एक < 0>, काम किया, टेम्पलेट्स ए और बी विभिन्न टीयू के से आया है। निश्चित रूप से, लिंकर बार-बार कंपाइलर का आह्वान कर रहा था, लेकिन सभी नाम लुकअप ठीक काम करते थे। Instantiation A < 1> A.cpp से नाम मिले जो B.cpp में अदृश्य थे।

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