2015-11-28 15 views
26

मैं निम्नलिखित कोड है:अस्पष्ट सी ++ ऑपरेटर ओवरलोडिंग

#include <iostream> 

using namespace std; 

ostream& f(ostream& os) { 
    return os << "hi"; 
} 

int main() { 
    cout << "hello " << f << endl; 
    return 0; 
} 

और किसी भी तरह इस काम करता है - उत्पादन होता है "हैलो हाय"। यह संकलक द्वारा व्याख्या कैसे किया जाता है? मुझे समझ में नहीं आता कि स्ट्रीम में फ़ंक्शन कैसे डाला जा सकता है।

+5

एक अधिभारित 'ऑपरेटर <<' है जो एक फ़ंक्शन स्वीकार करता है और उसे कॉल करता है। यह कितना अस्पष्ट है? –

+6

इस तरह से विभिन्न 'std :: endl' या 'std :: flush' अधिभार काम भी करते हैं। –

उत्तर

30

std::ostream एक operator<< अधिभार कि इस तरह के एक आप ने लिखा (number 11 in this list) के रूप में हस्ताक्षर के साथ एक समारोह के लिए एक सूचक प्राप्त करता है: endl वास्तव में एक समारोह के समान है दिया गया कार्य स्वयं को तर्क के रूप में गुजर रहा है। यह अधिभार (कई समान अन्य लोगों के साथ) आपको धारा मैनिपुलेटर्स लागू करने की अनुमति देने के लिए है, यानी << के साथ स्ट्रीम में आप जो सामान आउटपुट करते हैं और वहां से स्ट्रीम की स्थिति बदलते हैं। उदाहरण के लिए, का (गलत) सर्वव्यापक std::endl लागू किया जा सकता के रूप में

std::ostream &myendl(std::ostream &s) { 
    s<<'\n'; 
    s.flush(); 
    return s; 
} 

तो वास्तव में इस्तेमाल किया जा सकता है जो हमारे संस्करण के रूप में "नियमित" std::endl:

std::cout<<"Hello, World!"<<myendl; 

(वास्तविक क्रियान्वयन टेम्प्लेटेड है और थोड़ा और जटिल क्योंकि इसे व्यापक धाराओं के साथ भी काम करना है, लेकिन आपको विचार मिला है)

8

std::ostream::operator<< में एक अधिभार है जो फ़ंक्शन को पैरामीटर के रूप में स्वीकार करता है; और उस अधिभार का शरीर दिया गया कार्य आमंत्रित करना है।

यह वास्तव में endl वास्तव में कैसे काम करता है।

basic_ostream& operator<<(
    std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&)); 

जो सिर्फ कॉल:

ostream &endl(ostream &os) 
{ 
    os << '\n'; 
    os.flush(); 
    return os; 
} 
+0

मुझे जांचना होगा, लेकिन मुझे नहीं लगता कि इसमें कोई टेम्पलेट शामिल है (इस तथ्य को अनदेखा करना कि 'ostream'' basic_ostream' का एक उत्थान है)। AFAIR, 'ostream' और 'ios_base' लेने वाले कार्यों के लिए केवल दो ओवरलोड हैं। –

+0

@UlrichEckhardt अच्छी तरह से, टेम्पलेट पैरामीटर 'चार्ट' और 'लक्षण 'हैं। स्पष्टीकरण के लिए संपादित करेंगे क्योंकि आप बताते समय भ्रामक हैं। –

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