2009-11-02 14 views
6

मैं कोड का टुकड़ा निम्नलिखित है की वैध स्थिर सदस्य समारोह का उपयोग करना:वर्ग स्थापित नहीं किया जा सकता

यह जीसीसी-3.4 के तहत समस्याओं के बिना संकलित, जीसीसी-4.3, इंटेल संकलक, लेकिन MSVC9 तहत विफल रहता है।

MSVC "अपरिभाषित प्रकार c_traits<C> के उपयोग, बताता सी = कम से वर्ग टेम्पलेट सदस्य समारोह void foo<C>::go(void) संयोजित करते समय।

बिंदु यह संकलक अप्रयुक्त वर्ग के अप्रयुक्त सदस्य समारोह स्थापित करने के लिए कोशिश करता है, क्योंकि इस वर्ग के बस है सब पर इस्तेमाल नहीं किया।

मैं पूरी क्लास foo विशेषज्ञता बजाय विशेषज्ञता अपने सदस्य समारोह से काम के आसपास सकता है मुद्दा। लेकिन यह बात पूरी क्लास विशेषज्ञता विभिन्न कारणों के लिए मेरे लिए थोड़ा सा समस्याग्रस्त है कि।

बड़ा प्रश्न: सही क्या है?

  • मेरे कोड गलत है और क्योंकि वे foo पूरी तरह से स्थापित नहीं करते जीसीसी और इंटेल संकलक सिर्फ मुद्दे पर ध्यान न दें, या
  • कोड सही है और इस MSVC9 (वीसी 2008) बग है कि यह स्थापित करने के लिए कोशिश करता है अप्रयुक्त सदस्य कार्य?

कोड:

class base_foo { 
public: 
    virtual void go() {}; 
    virtual ~base_foo() {} 
}; 
template<typename C> 
struct c_traits; 

template<> 
struct c_traits<int> { 
    typedef unsigned int_type; 
}; 

template<typename C> 
class foo : public base_foo { 
public: 
    static base_foo *create() 
    { 
     return new foo<C>(); 
    } 
    virtual void go() 
    { 
     typedef typename c_traits<C>::int_type int_type; 
     int_type i; 
     i=1; 
    } 
}; 

template<> 
base_foo *foo<short>::create() 
{ 
    return new base_foo(); 
} 

int main() 
{ 
    base_foo *a; 
    a=foo<short>::create(); delete a; 
    a=foo<int>::create(); delete a; 
} 
+2

+1। – GManNickG

उत्तर

3

दोनों कंपाइलर्स यहां हैं; आपके मामले के लिए व्यवहार अनिर्दिष्ट है। आईएसओ सी ++ 14.7.1 [temp.inst]/9:

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

इस के लिए तर्क काफी सरल है: एक आभासी समारोह एक vtable प्रविष्टि की आवश्यकता है, और आभासी प्रेषण के साथ, यह संकलक का निर्धारण करने के लिए कि कोई आभासी समारोह वास्तव में नहीं कहा जाता है या मुश्किल हो सकता है। इसलिए, आईएसओ सी ++ छोटे कोड उत्पन्न करने के लिए कंप्यूटर्स को ऐसे उन्नत विश्लेषण करने की अनुमति देता है, लेकिन इसकी आवश्यकता नहीं होती है - इसलिए, एक सी ++ प्रोग्रामर के रूप में, आपको हमेशा यह मानना ​​चाहिए कि सभी आभासी कार्यों को हमेशा चालू किया जाएगा। अच्छा, संक्षिप्त, संकलित कोड के लिए

+1

जो मुझे कुछ भी अनुच्छेद 3 पर रुकने के लिए सिखाएगा। –

+0

ठीक है आपको कहीं भी रोकना है :) लेकिन इससे भी बदतर हो सकता है - कभी-कभी सी ++ में आपको विशेष रूप से इस तरह के और इस तरह के अनुभाग में कहा जाता है, 15.2 कहता है, और फिर यह पता चला कि एक और पैराग्राफ था जो उन नियमों को कहीं भी बदलता है 3.7 (एक आगे संदर्भ के साथ)। यह लगभग डी एंड डी नियम किताबों को धड़कता है। –

+0

ठीक है धन्यवाद। तो मेरा कोड गलत है;) – Artyom

1

अप्रयुक्त कार्यों को हटाने नहीं जोड़ने पर संकलन पर जहाँ आप अपने त्रुटि हो रही है हो जाएगा। एमएसवीसी नहीं जानता कि सभी संकलन इकाइयों में से किसके संकलन किए जा रहे हैं जो आखिरकार उस विधि को कॉल करेंगे। यह तब तक नहीं पता जब तक संकलन पूर्ण नहीं हो जाता है और लिंकिंग होने तक। स्वाभाविक रूप से विभिन्न कंपाइलर इस बारे में बेहतर हो सकते हैं, लेकिन मुझे संदेह है कि यह हो रहा है कि क्या हो रहा है।

मैं अपने विशिष्ट संकलक त्रुटियों लगता है जैसे कि यह आप केवल आगे होने के कारण होता है पर शक घोषित

template<typename C> 
struct c_traits; 

आप पूरी तरह से वर्ग निर्दिष्ट नहीं किया है।

template<typename C> 
struct c_traits 
{ 
    // some default/dummy int type 
}; 

मैं इस कम से कम शिकायत से संकलक बंद कर देंगे संदेह है: आप के रूप में सरल कुछ के रूप में की कोशिश की थी।

संपादित

इस वर्ग टेम्पलेट्स के लिए आम तौर पर गलत है। वर्ग टेम्पलेट्स के सदस्य कार्यों संकलित (और उनके शरीर में किसी भी त्रुटि शुरू हो रहा होना चाहिए नहीं कर रहे हैं) जब तक कि वे

instantiated रहे हैं टेम्पलेट में इस मामले में instantiated है होना चाहिए नहीं कर रहे हैं का रूप:

foo<short> 

कंपाइलर इसे किसी अन्य वर्ग के रूप में मानता है जिसकी विधियों के बाहरी संबंधों के लिए संभावित क्षमता है।मैंने कोई विशेष भाषा नियम नहीं सुना है जो कहता है कि बाह्य संबंध टेम्पलेट्स पर लागू नहीं होता है ...?

+0

वह शिकायत कर रहा है कि संकलक वर्चुअल विधि को संकलित करने की भी कोशिश कर रहा है, क्योंकि वह विधि को कॉल नहीं कर रहा है, और कक्षा को तुरंत चालू नहीं कर रहा है। –

+0

मैंने आपके सुझावों का प्रयास किया: लेकिन यह शिकायत करता है कि 'int_type' अपरिभाषित है। – Artyom

+0

@Artyom: मुझे लगता है डौग का मतलब है कि आप एक डमी typedef जहां उसकी टिप्पणी थी की आपूर्ति करना चाहिए: टेम्पलेट struct c_traits { \t typedef int int_type; }; – Eclipse

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