2010-10-25 20 views
11

मुझे टेम्पलेट कक्षाओं के लिए कुछ ऑपरेटर ओवरलोड को परिभाषित करने में कुछ समस्याएं आ रही हैं। चलिए उदाहरण के लिए इस hypothetical कक्षा लेते हैं।कक्षा टेम्पलेट्स पर ऑपरेटर ओवरलोडिंग

template <class T> 
class MyClass { 
    // ... 
}; 
  • ऑपरेटर + =

    इस संकलक त्रुटि में
    // In MyClass.h 
    MyClass<T>& operator+=(const MyClass<T>& classObj); 
    
    
    // In MyClass.cpp 
    template <class T> 
    MyClass<T>& MyClass<T>::operator+=(const MyClass<T>& classObj) { 
        // ... 
        return *this; 
    } 
    

    परिणाम:

    no match for 'operator+=' in 'classObj2 += classObj1' 
    
  • ऑपरेटर < <

    // In MyClass.h 
    friend std::ostream& operator<<(std::ostream& out, const MyClass<T>& classObj); 
    
    
    // In MyClass.cpp 
    template <class T> 
    std::ostream& operator<<(std::ostream& out, const MyClass<T>& classObj) { 
        // ... 
        return out; 
    } 
    
    इस संकलक चेतावनी में

    परिणाम:

    friend declaration 'std::ostream& operator<<(std::ostream&, const MyClass<T>&)' declares a non-template function 
    

क्या मैं गलत यहाँ कर रहा हूँ?

+0

आप कुछ वास्तविक कोड है जो संकलित करने के लिए विफल रहता है पोस्ट कर सकते हैं? – Naveen

+0

@ नवीन: आप एक ज़िप संस्करण प्राप्त कर सकते हैं http://www.box.net/shared/v23rj2f8e7 – Pieter

उत्तर

7
// In MyClass.h 
MyClass<T>& operator+=(const MyClass<T>& classObj); 


// In MyClass.cpp 
template <class T> 
MyClass<T>& MyClass<T>::operator+=(const MyClass<T>& classObj) { 
    // ... 
    return *this; 
} 

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

संपादित करें: तकनीकी रूप से, मानक के अनुसार, टेम्पलेट्स निर्यात करना संभव है, हालांकि बहुत कम कंपाइलर्स इसका समर्थन करते हैं। इसके अलावा, आप उपरोक्त भी कर सकते हैं यदि टेम्पलेट स्पष्ट रूप से MyClass.cpp में सभी प्रकार के लिए तत्काल है - लेकिन वास्तविकता में, जो आमतौर पर टेम्पलेट के बिंदु को रोकता है।

अधिक संपादन: मैं आपके कोड के माध्यम से पढ़ता हूं, और इसे कुछ काम की ज़रूरत है, उदाहरण के लिए ओवरलोडिंग ऑपरेटर []। इसके अलावा, आम तौर पर, मैं टेम्पलेट पैरामीटर का आयाम हिस्सा बनाउंगा, जो संकलन-समय पर पकड़े जाने के लिए + या + = की विफलता की अनुमति देता है, और इस प्रकार को आवंटित रूप से आवंटित किया जा सकता है। आपकी अपवाद कक्षा को std :: अपवाद से भी प्राप्त करने की आवश्यकता है। हालांकि, उनमें से कोई भी संकलन-समय त्रुटियों को शामिल नहीं करता है, वे बस महान कोड नहीं हैं।

0

आप निर्दिष्ट करना होगा कि एक टेम्पलेट समारोह है दोस्त:

MyClass<T>& operator+=<>(const MyClass<T>& classObj); 

विवरण के लिए this सी ++ पूछे जाने वाले प्रश्न लाइट जवाब।

12

आप कहते हैं की जरूरत है निम्नलिखित (जब से तुम एक पूरी टेम्पलेट के बजाय सिर्फ इसके बारे में एक विशेषज्ञता है, जो मामले में आप सिर्फ operator<< के बाद एक <> जोड़ने के लिए की आवश्यकता होगी दोस्ती):

template<typename T> 
friend std::ostream& operator<<(std::ostream& out, const MyClass<T>& classObj); 

असल में, इसे एक दोस्त के रूप में घोषित करने की आवश्यकता नहीं है जब तक कि यह निजी या संरक्षित सदस्यों तक पहुंच न जाए। चूंकि आपको बस चेतावनी मिलती है, ऐसा लगता है कि दोस्ती की घोषणा एक अच्छा विचार नहीं है। यदि आप एक दोस्त के रूप में एकल विशेषज्ञता घोषित करना चाहते हैं, तो आप अपनी कक्षा से पहले टेम्पलेट की अग्रेषित घोषणा के साथ नीचे दिखाए गए जैसा कर सकते हैं, ताकि operator<< को टेम्पलेट के रूप में मान्यता प्राप्त हो।

// before class definition ... 
template <class T> 
class MyClass; 

// note that this "T" is unrelated to the T of MyClass ! 
template<typename T> 
std::ostream& operator<<(std::ostream& out, const MyClass<T>& classObj); 

// in class definition ... 
friend std::ostream& operator<< <>(std::ostream& out, const MyClass<T>& classObj); 

उपरोक्त दोनों और इस तरह से मित्र के रूप में यह की विशेषज्ञता की घोषणा है, लेकिन पहले मित्र के रूप में सभी विशेषज्ञताओं वाणी, जबकि दूसरा केवल एक दोस्त जिसका TT के बराबर है के रूप में operator<< की विशेषज्ञता वाणी दोस्ती देने वाली कक्षा का।

और अन्य मामले में, अपने घोषणा ठीक लग रहा है, लेकिन ध्यान दें कि आप नहीं कर सकते += एक एक MyClass<U> को MyClass<T>T और U अलग प्रकार का घोषणा के साथ कर रहे हैं जब (जब तक आप उन प्रकार के बीच एक अंतर्निहित रूपांतरण है)। आप अपने += एक सदस्य टेम्पलेट

// In MyClass.h 
template<typename U> 
MyClass<T>& operator+=(const MyClass<U>& classObj); 


// In MyClass.cpp 
template <class T> template<typename U> 
MyClass<T>& MyClass<T>::operator+=(const MyClass<U>& classObj) { 
    // ... 
    return *this; 
} 
2

http://www.parashift.com/c++-faq-lite/template-friends.html

यह मैं ठीक उसी समस्या के साथ मदद की।

Soln:

  1. फॉरवर्ड वर्ग खुद की परिभाषा से पहले दोस्त समारोह की घोषणा। पूर्व के लिए:

    template<typename T> class MyClass; // pre-declare the template class itself 
        template<typename T> std::ostream& operator<< (std::ostream& o, const MyClass <T>& x); 
    
  2. के साथ "<>" समारोह नाम के साथ जोड़ दिया अपनी कक्षा में अपने दोस्त समारोह घोषित।

    friend std::ostream& operator<< <> (std::ostream& o, const Foo<T>& x); 
    
+0

लिंक टाइमआउट की ओर जाता है। – TobiMcNamobi

-1

इस तरह काम करता है:

class A 
{ 
    struct Wrap 
    { 
     A& a; 
     Wrap(A& aa) aa(a) {} 
     operator int() { return a.value; } 
     operator std::string() { stringstream ss; ss << a.value; return ss.str(); } 
    } 
    Wrap operator*() { return Wrap(*this); } 
}; 
संबंधित मुद्दे