2010-02-10 16 views
9

मेरी लाइब्रेरी के कुछ कार्यों के परिणाम का परीक्षण और प्रदर्शन करने के लिए, मैं आसान कार्यों का एक सेट बना रहा हूं।वैश्विक प्रकार के रूपांतरण ऑपरेटर को ओवरलोड करना

template <typename R, typename I> 
std::string execute(const std::string& func_name, R(*func_ptr)(const I&), const I& func_input); 

यह फ़ंक्शन को कॉल करने, और एक स्वरूपित स्ट्रिंग है कि मैं std::cout को भेज सकते हैं में परिणाम और तर्क प्रदर्शित:

मैं एक execute समारोह है कि लगता है कि नहीं है।

समस्या यह है कि मेरे कुछ कार्य परिवर्तनीय-टू-स्ट्रिंग परिणाम वापस नहीं लौटते हैं। मैंने सोचा कि मैं बस की तरह कुछ के साथ वैश्विक ::operator std::string ओवरलोड सकता है:

template <typename T> 
operator std::string(const std::vector<T>& v); 

लेकिन जीसीसी की शिकायत:

error: 'operator std::string(const std::vector<T, std::allocator<_CharT> >&)' must be a nonstatic member function 

ठीक है, निश्चित रूप से समस्या यह है कि मैं भी नहीं के लिए std::vector के सदस्य ऑपरेटरों जोड़ सकते हैं, और है मेरी कक्षाएं, मैं उन्हें "परीक्षण के लिए" रूपांतरण ऑपरेटरों के साथ प्रदूषित नहीं करना चाहता हूं।

मुझे लगता है कि मैं संकेतक की एक परत जोड़ सकता हूं और रूपांतरण ऑपरेटर की बजाय फ़ंक्शन का उपयोग कर सकता हूं, लेकिन यह अधिक सौंदर्य समाधान नहीं होगा। मैं ::operator << को std::ostream के लिए भी अधिभारित कर सकता हूं और std::ostringstream का उपयोग कर सकता हूं, लेकिन यह भी सबसे साफ समाधान नहीं है।

मुझे आश्चर्य हुआ कि क्या वैश्विक रूपांतरण ऑपरेटर वास्तव में अधिभार योग्य नहीं है, और यदि ऐसा है, तो क्यों।

उत्तर

10

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

इस पर निर्भर करता है कि आप इसे डीबग भाग में कितना प्रयास करना चाहते हैं, आप मेटाप्रोग्रामिंग का उपयोग विभिन्न वास्तविक कार्यान्वयन के लिए आगे बढ़ाने के लिए कर सकते हैं, जो सामग्री को मुद्रित करने वाले कंटेनर के लिए विशिष्ट प्रदान करते हैं।

आप अपने प्रकार के लिए operator<< क्यों नहीं देना चाहते हैं? मुझे लगता है कि वास्तव में मूर्खतापूर्ण समाधान है।अन्य भाषाओं के विपरीत जो आप प्रिंट करने योग्य परिणामों का उत्पादन करने के लिए स्ट्रिंग में कनवर्ट करने के तरीकों का उपयोग करते हैं, सी ++ में बेवकूफ तरीका operator<< प्रदान कर रहा है और फिर stringstreams (या boost::lexical_cast या कुछ समान समाधान) का उपयोग operator<< कार्यान्वयन के आधार पर स्ट्रिंग में कनवर्ट करने के लिए कर रहा है। यदि आप प्रारंभ बिंदु के लिए इसका उपयोग करना चाहते हैं तो operator<< को ओवरराइड करने वाले तत्वों से string बनाने के लिए एक सरल उपयोगिता कक्षा here है।

1

कोई उपयोगकर्ता परिभाषित वैश्विक रूपांतरण ऑपरेटर नहीं है। आपको या तो लक्ष्य प्रकार को नियंत्रित करना होगा (जिस स्थिति में एक गैर स्पष्ट एक पैरामीटर कन्स्ट्रक्टर रूपांतरण ऑपरेटर है) या स्रोत प्रकार (जिस स्थिति में आपको सदस्य ऑपरेटर लक्ष्य() को अधिभारित करना होगा)।

4

मुझे आश्चर्य हुआ कि क्या वैश्विक रूपांतरण ऑपरेटर वास्तव में अधिभार योग्य नहीं है, और यदि ऐसा है, तो क्यों।

नहीं, ऐसी कोई बात नहीं है। रूपांतरण कार्य एक वर्ग का सदस्य होना चाहिए। यदि ऐसा नहीं होता है, तो यह अस्पष्टता को पेश करके संकलक के लिए विशेष रूप से परेशानी वाली समस्या को अधिभारित करेगा।

+1

लेकिन कई ऑपरेटरों वैश्विक या सदस्य के रूप में उपलब्ध हैं, क्यों नहीं इस एक? उदाहरण के लिए, यदि कोई वैश्विक और सदस्य ऑपरेटर << है, तो संकलक एक संदिग्ध कॉल के लिए शिकायत करता है, यह कनवर्टन के साथ एक ही चीज़ कर सकता है। – NewbiZ

+2

रूपांतरण फ़ंक्शन विशेष सदस्य फ़ंक्शंस (जैसे ctor, dtor, op = और copy-constructor हैं) क्योंकि वे रूपांतरण/ऑब्जेक्ट सृजन में भाग लेते हैं। 12.3 देखें। – dirkgently

0

एक रूपांतरण फ़ंक्शन सदस्य कार्य होना चाहिए। फ़ंक्शन एक रिटर्न प्रकार निर्दिष्ट नहीं कर सकता है, और पैरामीटर सूची खाली होनी चाहिए। उन्हें कम से कम इस्तेमाल किया जाना चाहिए और एक प्रकार से दूसरे प्रकार के लिए एक स्पष्ट रूपांतरण पथ होना चाहिए। अन्यथा वे अप्रत्याशित परिणाम और रहस्यमय त्रुटियों का कारण बन सकते हैं।

0

दुर्भाग्यवश वैश्विक कास्टिंग ऑपरेटर जैसी कोई चीज़ नहीं है। हैरानी की बात है। लेकिन टेम्पलेट्स आपका दोस्त हैं।

कभी-कभी आप इंटरफ़ेस में कास्टिंग का पर्दाफाश नहीं करना चाहते हैं, तो यह अज्ञात केवल एक विशिष्ट कार्यान्वयन के लिए रखना होगा। मैं आमतौर पर कक्षा में() विधि के रूप में एक टेम्पलेट जोड़ता हूं जो कि कास्ट में चेक टाइप भी कर सकता है और आपको जिस तरह से आप कास्टिंग को कार्यान्वित करना चाहते हैं उसे संभाल सकता है (उदा। गतिशील, साझा, रेफरी इत्यादि)।

कुछ इस तरह:

template< class EvtT >const EvtT& as() const throw(std::exception) 
    { 
     const EvtT* userData = static_cast<const EvtT*>(m_UserData); 
     ASSERT(userData, "Fatal error! No platform specific user data in input event!"); 
     return *userData; 
    } 

m_UserData एक गुमनाम प्रकार केवल कार्यान्वयन जानता है जो है। हालांकि यह सख्ती से एक गैर-टाइप की गई कास्ट है (मैं यहां टाइप सीक का उपयोग नहीं करता) इसे एक गतिशील_कास्ट और उचित कास्टिंग अपवादों द्वारा प्रतिस्थापित किया जा सकता है।

कार्यान्वयन बस इस करता है:

unsigned char GetRawKey(const InputEvent& ie) 
    { 
     const UserEvent& ue = ie.as<const UserEvent>(); 
     ... 
संबंधित मुद्दे