5

मैं आदेश से प्रचुरता से फ़ाइलों के सैकड़ों में instantiated जा रहा है, मैं करने के लिए एक एकल के लिए मजबूर करने में एक भी सीपीपी में template class std::shared_ptr<SomeWidelyUsedClass> लगा सके लगाना std::shared_ptr<SomeWidelyUsedClass> को रोकने के लिए तुरंत #include <memory> के बाद (प्रतीत होता है) stdafx.h में extern template class std::shared_ptr<SomeWidelyUsedClass> का उपयोग कर के उज्जवल विचार था तत्कालता और आशा है कि संकलन/लिंक समय पर सहेजें। हालांकि, परिणामी .cod और .obj फ़ाइलों की जांच से पता चलता है कि shared_ptr<SomeWidelyUsedClass> कोड हर जगह बनाया जा रहा है। लेकिन अगर मैं अपनी खुद की टेम्पलेट कक्षा के साथ इस सटीक तकनीक का उपयोग करता हूं, तो यह अपेक्षा के अनुसार काम करता है। क्या shared_ptr के बारे में कुछ खास है जो इस उपयोग को रोकता है? शायद <memory> में कुछ ऐसा है जो संकलक को extern template कथन तक पहुंचने से पहले एक तात्कालिकता बनाने के लिए मजबूर करता है (मुझे यकीन है कि stdafx.h में कुछ भी ऊपर नहीं है जो shared_ptr का उपयोग करता है)?share_ptr के साथ "बाहरी टेम्पलेट" क्यों काम नहीं करेगा?

स्पष्ट करने के लिए:

// stdafx.h; included in every cpp in the project 
#include <memory> 
#include "SomeWidelyUsedClass.h" // no shared_ptr in here 

// I expect this to prevent instantiation of std::shared_ptr<SomeWidelyUsedClass> 
// in all compilation units that include this, except the one below. 
extern template class std::shared_ptr<SomeWidelyUsedClass>; 

तब:

// ExplicitTemplateInstantiations.cpp 
#include "stdafx.h" 

// I expect this to cause std::shared_ptr<SomeWidelyUsedClass> 
// to be instantiated in this compilation unit 
template class std::shared_ptr<SomeWidelyUsedClass>; 

और:

// SomeOtherFile.cpp 
#include "stdafx.h" 
#include "SomeWidelyUsedClass.h" 

void foo() 
{ 
    // I expect that SomeOtherFile.obj will not include an instantiation of 
    // std::shared_ptr<SomeWidelyUsedClass> since it was declared extern in stdafx.h 
    std::shared_ptr<SomeWidelyUsedClass>(new SomeWidelyUsedClass()); 
} 
+0

कुछ कोड होने से समस्या को समझने और निदान करने में मदद मिलेगी। –

+0

डुनो, सवाल उतना उचित लगता है जितना यह है। हालांकि, जवाब नहीं पता। –

+0

@RSahu कोड – dlf

उत्तर

6

मानक §14.7.2/10 में कहते हैं:

उत्कृष्टता इनलाइन फ़ंक्शंस और क्लास टेम्पलेट स्पेशलाइजेशन के लिए पीटी, स्पष्ट तत्काल घोषणाओं में उस इकाई के अंतर्निहित तत्कालता को दबाने के प्रभाव का संदर्भ है, जिसे वे संदर्भित करते हैं।

मैंने अभी वीएस2013 में चेक किया है और std::shared_ptr<> के कार्यान्वयन में एक इनलाइन कन्स्ट्रक्टर है। शायद यही कारण है कि आपके extern template को अनदेखा किया गया है।

+1

मुझे विश्वास है कि यह है। इसके अलावा, मुझे बस एमएस दस्तावेज़ों में इस नोट को निर्देशित किया गया था: "विशेषज्ञता में बाहरी कीवर्ड केवल कक्षा के शरीर के बाहर परिभाषित सदस्य कार्यों पर लागू होता है। कक्षा घोषणा के भीतर परिभाषित कार्यों को इनलाइन फ़ंक्शंस माना जाता है और हमेशा तत्काल होते हैं । " – dlf

+0

प्रयोग इसकी पुष्टि करता है। खिलौने टेम्पलेट वर्ग के लिए मैंने प्रश्न में संदर्भित किया है, अगर मैं कक्षा निकाय के बाहर के कार्यों को परिभाषित करता हूं, तो 'बाहरी टेम्पलेट' काम करता है। अगर मैं उन्हें इसके भीतर परिभाषित करता हूं, तो ऐसा नहीं होता है। – dlf

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