2012-05-24 19 views
64

आहऑपरेटर << रखना चाहिए ठीक एक तर्क

#include "logic.h" 
... 

class A 
{ 
friend ostream& operator<<(ostream&, A&); 
... 
}; 

logic.cpp

#include "a.h" 
... 
ostream& logic::operator<<(ostream& os, A& a) 
{ 
... 
} 
... 

जब मैं संकलन, यह कहते हैं:

std :: ostream & तर्क :: ऑपरेटर < < (std :: ostream &, ए &) 'बिल्कुल एक लेना चाहिए तर्क।

समस्या क्या है?

उत्तर

90
समस्या

है कि आप इसे वर्ग के भीतर परिभाषित है, जो

एक) का अर्थ है दूसरा तर्क निहित है (this) और

ख) यह क्या आप यह कर चाहते हैं काम नहीं चलेगा, अर्थात् का विस्तार है std::ostream

आप एक नि: शुल्क समारोह के रूप में इसे परिभाषित करना होगा:

class A { /* ... */ }; 
std::ostream& operator<<(std::ostream&, const A& a); 
+7

इसके अलावा, वह के रूप में एक दोस्त समारोह में यह घोषणा करता है, और यह परिभाषित करता है एक के रूप में मेबर समारोह। – asaelr

40

एक दोस्त ने समारोह एक सदस्य समारोह नहीं है, तो समस्या यह है कि आप A के एक दोस्त के रूप में operator<< घोषित है:

friend ostream& operator<<(ostream&, A&); 

तो वर्ग logic

ostream& logic::operator<<(ostream& os, A& a) 
      ^^^^^^^ 
के एक सदस्य समारोह के रूप में यह परिभाषित करने की कोशिश

क्या आप इस बारे में उलझन में हैं कि logic एक कक्षा या नामस्थान है?

त्रुटि इसलिए है क्योंकि आपने एक सदस्य operator<< को दो तर्क लेने के लिए परिभाषित करने का प्रयास किया है, जिसका अर्थ यह है कि इसमें तीन तर्क होते हैं जिसमें अंतर्निहित this पैरामीटर शामिल है। ऑपरेटर केवल दो तर्क ले सकता है, ताकि जब आप a << b लिखते हैं तो दो तर्क a और b होते हैं।

आप ostream& operator<<(ostream&, const A&) एक गैर -Member समारोह के रूप में परिभाषित करना चाहते हैं निश्चित रूप से नहीं logic के सदस्य के रूप क्योंकि यह उस वर्ग के साथ कोई संबंध नहीं है!

std::ostream& operator<<(std::ostream& os, const A& a) 
{ 
    return os << a.number; 
} 
0

मैं templated कक्षाओं के साथ इस समस्या में भाग गया। यहाँ एक अधिक सामान्य समाधान मैं का इस्तेमाल किया था है:

template class <T> 
class myClass 
{ 
    int myField; 

    // Helper function accessing my fields 
    void toString(std::ostream&) const; 

    // Friend means operator<< can use private variables 
    // It needs to be declared as a template, but T is taken 
    template <class U> 
    friend std::ostream& operator<<(std::ostream&, const myClass<U> &); 
} 

// Operator is a non-member and global, so it's not myClass<U>::operator<<() 
// Because of how C++ implements templates the function must be 
// fully declared in the header for the linker to resolve it :(
template <class U> 
std::ostream& operator<<(std::ostream& os, const myClass<U> & obj) 
{ 
    obj.toString(os); 
    return os; 
} 

अब: * मेरी toString() समारोह इनलाइन अगर यह सीपीपी में रखा जा रहा है नहीं हो सकता। * आप हेडर में कुछ कोड से फंस गए हैं, मैं इससे छुटकारा नहीं पा सका। * ऑपरेटर toString() विधि को कॉल करेगा, यह रेखांकित नहीं है।

ऑपरेटर का शरीर < < को मित्र क्लॉज या कक्षा के बाहर घोषित किया जा सकता है। दोनों विकल्प बदसूरत हैं।:(

शायद मैं गलत समझ रहा हूँ या कुछ याद आ रही है, लेकिन सिर्फ आगे की घोषणा ऑपरेटर टेम्पलेट जीसीसी में से नहीं जुड़ता है

यह भी काम करता है:।

template class <T> 
class myClass 
{ 
    int myField; 

    // Helper function accessing my fields 
    void toString(std::ostream&) const; 

    // For some reason this requires using T, and not U as above 
    friend std::ostream& operator<<(std::ostream&, const myClass<T> &) 
    { 
     obj.toString(os); 
     return os; 
    } 
} 

मुझे लगता है कि आप भी कर सकते हैं templating मुद्दों हेडर में घोषणाओं के लिए मजबूर है, यदि आप एक माता पिता के वर्ग है कि ऑपरेटर < < लागू करने के लिए टेम्प्लेट की नहीं है का उपयोग करने से बचने, और एक आभासी toString का उपयोग() विधि।

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