2013-06-14 7 views
6

ओवरलोड करना मेरे पास होने वाली समस्या को फिर से बनाने के लिए कोड है। Base कक्षा वर्चुअल फ़ंक्शन foo के साथ एक टेम्पलेट क्लास है। foo में एक डिफ़ॉल्ट कार्यान्वयन है जो पारित तर्कों को जोड़ता है।एक सी ++ टेम्पलेट क्लास वर्चुअल फ़ंक्शन

SimpleDerivedBase से निकला, std::string के साथ इसका विशेषज्ञता। SimpleDerived आभासी Base<T>::foo() फ़ंक्शन ओवरलोड करता है। main में कॉल होने पर यह कक्षा ठीक से संकलित होती है और इसकी foo आउटपुट अपेक्षित होती है।

#include <iostream> 

template<class T> 
struct Base 
{ 
    virtual void foo(T val) 
    { 
     T local = val + val; // THE OFFENDING LINE OF CODE 
     std::cout << "Base" << std::endl; 
    } 
}; 

struct SimpleDerived : public Base<std::string> 
{ 
    virtual void foo(std::string val) 
    { 
     std::cout << "SimpleDerived" << std::endl; 
    } 
}; 

struct SimpleObject 
{ 
    int value; 
}; 

struct ComplexDerived : public Base<SimpleObject> 
{ 
    virtual void foo(SimpleObject val) 
    { 
     std::cout << "ComplexDerived" << std::endl; 
    } 
}; 

int main(void) 
{ 
    Base<int> base; 
    base.foo(2); 

    SimpleDerived simpleDerived; 
    simpleDerived.foo("hello world"); 

    SimpleObject object; 
    ComplexDerived complexDerived; 
    complexDerived.foo(object); 

    return 0; 
} 

ComplexDerivedBase से निकला है, एक कस्टम struct SimpleObject साथ यह विशेषज्ञता। ComplexDerived ओवरलोड foo भी। हालांकि, यह समस्या की जड़ है। यदि मैं यह संकलन करने की कोशिश मैं:

quicktest.cpp: In member function ‘void Base<T>::foo(T) [with T = SimpleObject]’: 
quicktest.cpp:47:1: instantiated from here 
quicktest.cpp:8:19: error: no match for ‘operator+’ in ‘val + val’ 

जाहिर है, वहाँ SimpleObject के लिए कोई ऑपरेटर "+" है। लेकिन यहां मेरा भ्रम है .. संकलक को Base<SimpleObject>::foo लागू करने के लिए कहा जा रहा है क्योंकि यह ComplexDerived से विरासत में है। हालांकि, मैं कभी भी Base<SimpleObject>::foo का उपयोग या कॉल नहीं करता हूं। तो क्या संकलक इस बेस क्लास फ़ंक्शन को उत्पन्न करने का प्रयास कर रहा है?

+0

आप इसे पहले ही जानते हैं, लेकिन चूंकि उत्तर यह पुष्टि करने के लिए प्रतीत होता है कि संकलक आपके बेस क्लास में वर्चुअल फ़ंक्शन को तुरंत चालू करने का प्रयास करेगा: आप टेम्पलेट विशेषज्ञता का उपयोग कर समस्या के आसपास काम कर सकते हैं (फ़ंक्शन शुद्ध आभासी बनाते हैं)। – kloffy

उत्तर

9

पैरा 14.7.1/C++ 11 मानक निर्दिष्ट की 10:

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

दूसरे शब्दों में, इस मामले में व्यवहार कार्यान्वयन-विशिष्ट है।

जबकि सिद्धांत में संकलक यह पता लगाने सकता है कि foo() के आधार वर्ग के कार्यान्वयन में कॉल कभी लागू नहीं किया जाएगा (के बाद से समारोह कॉल के लिए एक संदर्भ या सूचक के माध्यम से नहीं होती है) और यह instantiating से बचने के लिए इस, व्यवहार मानक द्वारा अनिवार्य नहीं है।

+0

धन्यवाद एंडी! बस fyi, मैं जी ++ ((उबंटू/लिनारो 4.6.3-1ubuntu5) 4.6.3 का उपयोग कर रहा था)। – user2130260

+0

@ user2130260: ठीक है, खुशी हुई यह मदद की :) –

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