2011-06-20 7 views
5

मैं विजुअल स्टूडियो से जीएनयू/लिनक्स पर जी ++ में अपनी खुद की lib को बंद करने की कोशिश कर रहा हूं, और मुझे टेम्पलेट संकलन के साथ कुछ समस्याएं आ रही हैं। दरअसल, विज़ुअल सी ++ में, टेम्पलेट केवल तब उत्पन्न होते हैं जब उन्हें स्पष्ट रूप से कोड में उपयोग किया जाता है, जबकि ऐसा लगता है (मेरी त्रुटियों से) कि g ++ पहले उपयोग किए जाने से पहले टेम्पलेट की सामग्री का मूल्यांकन करता है। बल्कि पहले की तुलना मेंमैं जी + + एमआईएमसी ++ के टेम्पलेट तत्काल व्यवहार की नकल कैसे कर सकता हूं?

error: incomplete type ‘X’ used in nested name specifier 

... क्योंकि मैं टेम्पलेट कोड के बाद कुछ वर्गों में शामिल हैं,: यह निम्न त्रुटि का परिणाम है। मैं क्रॉस-उपयोग संघर्ष के कारण ऐसा कर रहा हूं।

यह समझा जाता है कि विज़ुअल सी ++ उपयोग पर टेम्पलेट की सामग्री को हल करने का प्रयास नहीं करता है, और g ++ जितनी जल्दी हो सके संकल्प करता है।

class MyClass; 
template<class _Ty> 
void func(MyClass* a_pArg) 
{ 
    a_pArg->foo(); 
}; 

(_Ty नहीं किया जाता है, लेकिन यह कोई फर्क नहीं पड़ता है, यह सिर्फ समस्या को समझाने के लिए है)

उस मामले विजुअल C++ संकलन हैं (भले ही MyClass predeclared नहीं है) में, जबकि g ++ नहीं होगा, क्योंकि MyClass पूरी तरह से घोषित नहीं किया गया है।

क्या उपयोग करने के लिए टेम्पलेट्स को तुरंत चालू करने के लिए g ++ बताने का कोई तरीका है?

+0

बस स्पष्ट होना; आप कह रहे हैं कि * * MyClass' घोषित करें, फिर फ़ंक्शन टेम्पलेट को परिभाषित करें, फिर * * MyClass * को परिभाषित करें, और फिर अंत में टेम्पलेट को तुरंत चालू करें? –

+1

@ जुइसबॉक्स: पुhew! इस सवाल पर कुछ सर्जरी हुई। अगर मैंने कुछ तोड़ दिया तो कृपया मुझे बताएं। :) –

+5

@ जुइसबॉक्स: ध्यान दें कि अंडरस्कोर से शुरू होने वाले नामों का उपयोग (उदा। आपका '_Ty') एक बुरा विचार है क्योंकि वे कई मामलों में कार्यान्वयन के लिए आरक्षित हैं। –

उत्तर

9

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

आपके मामले में, MyClass एक टेम्पलेट पैरामीटर नहीं है, इसलिए यह चरण चरण में इसका निरीक्षण कर सकता है। इससे पहले कि आप को अपने कक्षा शीर्षलेख को शामिल करने के लिए की आवश्यकता है।

+0

हालांकि मैं उलझन में हूं - ऐसा लगता है कि अंतर एक चरण में कितना काम किया जाता है: एमएसवीसी को टेम्पलेट कोड को "देखने" की अनुमति देना है जो अनुक्रम में इसके बाद दिखाई देता है लेकिन समय से पहले। – Owen

+0

@ ओवेन: बड़ा मुद्दा यह है कि चरण 1 में ** कितना काम ** नहीं किया गया है। जब तक एमएसवीसी दूसरा चरण करता है, 'माईक्लास' एक पूर्ण प्रकार होता है, लेकिन तथ्य यह है कि मानक अनिवार्य है कि 'MyClass' को _first_ चरण के दौरान एक पूर्ण प्रकार होना चाहिए क्योंकि यह एक निर्भर प्रकार नहीं है। – ildjarn

1

जैसा कि यह किसी अन्य उत्तर में इंगित किया गया था, जीसीसी पहले लुकअप चरण में गैर-निर्भर नामों को सही दिख रहा है, और वीसी ++ दूसरे चरण में सबसे अधिक चेक को बदलता है (जो गलत है)। अपने कोड को ठीक करने के लिए, आपको gcc के कुछ टूटे हुए संस्करण की खोज करने की आवश्यकता नहीं है। आपको घोषणा और कार्यान्वयन को अलग करने की आवश्यकता है (कम से कम गैर-निर्भर नामों के लिए)। अपने उदाहरण का उपयोग करना,

// provide declarations 
class MyClass; 

template<class T> 
void func(MyClass* a_pArg); 

// provide definition of MyClass 
class MyClass 
{ 
    // watever 
}; 

// provide definition of func 
template<class T> 
void func(MyClass* a_pArg); 
{ 
    a_pArg->foo(); 
}; 
1

आप जीसीसी के बजाय बजना उपयोग करने के लिए तैयार हैं, तो बजना समर्थन -fdelayed-template-fms-extensions विकल्प विशेष रूप से MSVC कोड संकलित करने के लिए तैयार किया गया है से गर्भित (पार्स के अंत में टेम्पलेट इन्स्टेन्शियशन प्रदर्शन करने के लिए समर्पित) (और कई quirks)।

फ्रैंकोइस पिकेट के मुताबिक, जो एमएसवीसी कोड (और वास्तव में इसमें से अधिकतर) को पूरी तरह से संकलित करने के लिए सीएलएंग प्रयास का नेतृत्व कर रहा है, सीएलएंग सभी एमएफसी कोड को लगभग 2 से 3 महीनों में पार्स करने में सक्षम होना चाहिए, केवल कुछ ही गैर-मामूली मुद्दे शेष हैं। पहले से ही अधिकांश एमएफसी सही ढंग से व्याख्या की गई है (यानी, वीसी ++ के रूप में व्याख्या की जाती है)।

0

विजुअल सी ++ मानक द्वारा निर्दिष्ट डिफ़ॉल्ट दो चरण लुकअप द्वारा कार्यान्वित नहीं करता है।

हालांकि, दो चरण चरण की तरह दिखता है विजुअल स्टूडियो 2015 में/ज़ा विकल्प के साथ थोड़ा बेहतर है। शायद आप कुछ मामलों के लिए जीसीसी टेम्पलेट तत्काल व्यवहार की नकल करने के लिए/Za विकल्प जोड़कर विपरीत कर सकते हैं।

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