2010-01-07 7 views
6

मेरे पास बूस्ट :: किसी भी तरह की कक्षा है, जिसमें यह एक टेम्पलेट कंटेनर क्लास है। मैं एक स्ट्रिंग में निहित मान लिखने के लिए एक तरीका चाहते हैं। हालांकि, यदि निहित प्रकार स्ट्रीम प्रविष्टि ऑपरेटर प्रदान नहीं करता है, तो मैं संकलन करने में विफल होने की बजाय कुछ डिफ़ॉल्ट ट्रिंग वापस करने की विधि चाहता हूं। नीचे के रूप में पास के रूप में मैं आ गए है, और यह मैं क्या कर रहा हूँ के रूप में स्पष्ट करना चाहिए:सी ++ में "डिफ़ॉल्ट" स्ट्रीम प्रविष्टि ऑपरेटर कैसे बनाएं?

namespace W { 
    namespace hide { 
     template <typename T> 
     std::ostream& operator<<(std::ostream& out, const T& t) { 
      return std::operator<<(out, typeid(T).name()); 
     } 
    } 

    template <typename T> struct C { 

     T t_; 

     std::string ToString() const { 
      using namespace hide; 
      std::ostringstream oss; 
      oss << t_; 
      return oss.str(); 
     } 
    }; 
} 

यह बहुत अच्छी तरह से काम करता है, कुछ कैविएट्स के साथ। उदाहरण के लिए, यदि मैं वास्तव में कक्षा के लिए अधिभारित प्रविष्टि ऑपरेटर प्रदान करना चाहता हूं, तो उस ऑपरेटर को कक्षा के समान नामस्थान में होना चाहिए, या इसके लिए इसे डब्ल्यू नेमस्पेस में होना चाहिए।

इसमें किसी भी प्रकार की समस्या है जिसमें पहले से ही एक गैर-सदस्य std :: ऑपरेटर < < है, उदा। चार और std :: स्ट्रिंग। यदि टी उन प्रकारों में से एक है, तो ऊपर oss << t_ लाइन संदिग्ध हो जाती है।

std::ostream& operator << (std::ostream& out, const std::string& s) { 
    return std::operator <<(out, s); 
} 

मेरा प्रश्न, किसी को भी इस से एक बेहतर तरीका मिल गया है है: यह, डब्ल्यू नाम स्थान के अंदर इन प्रकार के भार के जोड़ने उदाहरण के लिए चारों ओर से काम किया जा सकता है? मुझे std :: string जैसी चीज़ों के लिए अपना खुद का ओवरलोड क्यों जोड़ना है? क्या यह सब मानक के अनुसार समर्थित है, या क्या मैं गैर-मानक व्यवहार का लाभ उठा रहा हूं? (मैं जी ++ 4.3.3 के साथ परीक्षण कर रहा हूं)

उत्तर

3

नीचे कुछ कोड है जो मुझे कुछ समय पहले एक कंपाइलर निर्माण वर्ग में याद करते हुए याद करते हैं। मैंने सोचा कि यह विशेष रूप से चालाक था (यदि 'साफ' नहीं है) तो मैंने इसे पकड़ लिया।

void (*printer)(std::ostream&, const void*); 
printer = print<T>; 

फिर बाद में निहित प्रदर्शित करने के लिए प्रिंटर() फ़ंक्शन का उपयोग करें:

से http://www.cs.colorado.edu/~main/a++/tree.h

// If data of type T can be printed with the usual << operator, then 
    // print<T>(out, p) will interpret *p as a T object and print its 
    // value to out. Otherwise, a message is printed to out, indicating 
    // that objects of type T are not printable. 
    template<typename T> void print(std::ostream& out, const void* p) 
    { 
    // The first part of this code sets an enum value, is_printable, to 
    // be 1 if the data type T can be printed with the usual << 
    // operator. Otherwise, is_printable is set to zero. The programming 
    // technique is based on a note from Herb Sutter at 
    // http://www.gotw.ca/gotw/071.htm 
    class object 
    { 
    public: 
     object(T convert) { }; 
    }; 
    char operator << (std::ostream&, const object&); 
    enum { is_printable = sizeof(std::cout << (*static_cast<T*>(0))) == sizeof(char) ? 0 : 1 }; 

     // Notice that the boolean expression in the if-statement is known at 
    // compile time, so that only one of the two output statements will be 
    // compiled into object code. 
    if (is_printable) 
     out << *static_cast<const T*>(p); 
    else 
     out << "(value of type " << typeid(T).name() << " cannot be printed)"; 
    } 

जब आप अपने कंटेनर वस्तु का निर्माण, चर के लिए प्रिंट कार्य करने के लिए एक सूचक पकड़

यदि संभव हो तो मूल्य।

उम्मीद है कि इससे मदद मिलती है।

+0

ऐसा लगता है कि यह मेरा कोई भी कस्टम स्ट्रीम सम्मिलन ऑपरेटर नहीं चुनता है। कॉन्स्ट ऑब्जेक्ट और ऑपरेटर को प्राथमिकता मिलती है, शायद क्योंकि इसे फ़ंक्शन का हिस्सा घोषित किया जाता है? यदि मैं ऑब्जेक्ट और उसके ऑपरेटर को खींचने का प्रयास करता हूं << फ़ंक्शन से बाहर यह कुछ भी मिलान करने में सक्षम नहीं होता है ... – JimSteele1222

+0

दरअसल, स्क्रैच करें: यह धारा प्रविष्टि ऑपरेटर को तब तक उठाता है जब तक वे एक ही नामस्थान में हों कक्षा टी। मुझे ऐसा कोई रास्ता नहीं दिख रहा है, उदाहरण के लिए, वेक्टर के लिए स्ट्रीम प्रविष्टि ऑपरेटर प्रदान करें। – JimSteele1222

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