2013-09-27 9 views
11

एक साधारण लकड़हारासार्वभौमिक संदर्भ द्वारा फ़ंक्शन पॉइंटर कैप्चर नहीं किया जाता है?

struct DebugOutput { 
    DebugOutput(std::ostream& out = std::cerr) : m_Out(out) {} 

    template<typename T> 
    inline DebugOutput& operator <<(T&& value) { 
     m_Out << value; 
     return *this; 
    } 
private: 
    std::ostream& m_Out; 
}; 

मुझे पता चला std::endluniversal reference द्वारा कब्जा कर लिया नहीं किया जाएगा लागू करने हैं।

DebugOutput dbg; 
dgb << std::endl; 

मैंने पाया इस this post जो यह बताती है कि आप संरचना जो विशेष रूप से समारोह सूचक हस्ताक्षर ले जाता है, यानी भीतर एक अतिभारित समारोह जोड़ने की जरूरत:

typedef std::ostream& (*StandardEndLine)(std::ostream&); 
inline DebugOutput& operator<<(StandardEndLine manip) { 
    return *this; 
} 

क्यों समारोह सूचक सार्वभौमिक द्वारा कब्जा कर लिया नहीं है संदर्भ? क्या यह int या void* जैसा कोई प्रकार नहीं है?

+0

यह एक टेम्पलेट/अधिभारित है। – Xeo

+3

http://stackoverflow.com/a/1136617/46642 –

+0

संभावित डुप्लिकेट [std :: endl अज्ञात प्रकार का है जब ऑपरेटर ओवरलोडिंग <<] (http://stackoverflow.com/questions/1134388/stdendl-is- अज्ञात-प्रकार-कब-ओवरलोडिंग-ऑपरेटर) – Xeo

उत्तर

12

एक फ़ंक्शन (पॉइंटर) को सार्वभौमिक संदर्भ से जोड़ा जा सकता है। उदाहरण:

void f(int) {} 

template <typename T> 
void foo(T&&) {} 

foo(f); // OK 

हालांकि, एक ओवरलोडेड फ़ंक्शन नहीं कर सकता है। यही कारण है, अगर आप f, कहते हैं की एक दूसरी अधिभार जोड़ने के लिए,

void f(double) {} 

कॉल foo(f) असफल हो जायेगी।

खुद को कंपाइलर जूते पर रखें। f से foo पास करने की आवश्यकता है और f नामक दो कार्य हैं जिनमें से प्रत्येक का एक अलग प्रकार है। अगर हम इस प्रकार को सूचित करते हैं, तो संकलक अनजाने में सही f चुन सकता है। उदाहरण के लिए,

foo(static_cast<void (*)(int)>(f)); 

ठीक संकलित करता है तथा void f(int) (समारोह करने के लिए सूचक रूपांतरण के बाद) foo को पारित करेंगे।

हालांकि, हम इस प्रकार को सूचित नहीं कर रहे हैं। हम संकलक को इसे कम करने के लिए कह रहे हैं।

इसी f करने के लिए, एक ही तर्क std::endl पर लागू होता है क्योंकि यह एक समारोह टेम्पलेट है और इसलिए, नाम std::endl एक ही नाम है, लेकिन विभिन्न प्रकार के साथ काम करता है का एक सेट, सभी का प्रतिनिधित्व करता है।

अब, आप देख सकते हैं कि त्रुटि का कारण यह तथ्य है कि हम एक अधिभार सेट प्रदान करते हैं और प्रकार की कटौती के लिए पूछते हैं। इसलिए, यह सार्वभौमिक संदर्भों के लिए विशेष नहीं है।

std::cout << std::endl काम करता है क्योंकि basic_ostream::operator << एक टेम्पलेट नहीं है और पारित तर्क के प्रकार को कम करने की कोशिश नहीं करता है। यह एक ऐसा कार्य है जो एक विशेष प्रकार का std::endl लेता है।

+0

बहुत स्पष्ट! धन्यवाद @ कैसियो-नेरी :) –

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

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