2012-10-15 12 views
8

मैं कुछ गणित की कक्षाओं (मैट्रिक्स, वेक्टर, आदि) एक दोस्त ने उल्लेख किया है कि std::complex के लिए ostream ऑपरेटर की जीसीसी मानक पुस्तकालय कार्यान्वयन के आंतरिक उपयोग भी शामिल है के लिए ostream ऑपरेटरों प्रदान करने में देख रहा हूँ एक स्ट्रिंग धारा यह वास्तविक ostream को पार करने से पहले उत्पादन फ़ॉर्मेट करने के लिए:उपयोग

/// Insertion operator for complex values. 
template<typename _Tp, typename _CharT, class _Traits> 
    basic_ostream<_CharT, _Traits>& 
    operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 
{ 
    basic_ostringstream<_CharT, _Traits> __s; 
    __s.flags(__os.flags()); 
    __s.imbue(__os.getloc()); 
    __s.precision(__os.precision()); 
    __s << '(' << __x.real() << ',' << __x.imag() << ')'; 
    return __os << __s.str(); 
} 

यह पैटर्न के रूप में अच्छी तरह से बढ़ावा में दिख रहा है। हम यह निर्धारित करने की कोशिश कर रहे हैं कि यह एक पैटर्न है जो निम्नलिखित है। इस बात की चिंता है कि इसमें स्ट्रिंग स्ट्रीम के लिए अतिरिक्त शीर्षलेख शामिल है और स्ट्रिंग स्ट्रीम के भीतर आवश्यक अतिरिक्त ढेर आवंटन हैं जो संभावित रूप से टाल जा सकते हैं।

सबसे उचित बात यह सुझाव दिया गया है कि यदि क्लाइंट को उस कार्यक्षमता की आवश्यकता है, तो वे स्ट्रिंग स्ट्रीम बना सकते हैं और प्री-पास स्वयं कर सकते हैं।

क्या कोई मुझे समझने में मदद कर सकता है कि इसे अच्छा अभ्यास क्यों माना जाएगा और क्या मुझे इसे अपनाना चाहिए?

उत्तर

6

पर विचार करें यदि आप ostream पर एक निर्गम चौड़ाई सेट क्या होता है, तो एक एसटीडी बारे में :: यह करने के लिए जटिल - करने के लिए सिर्फ पहला उत्पादन आपरेशन (यानी '(' चरित्र) को प्रभावित आप नहीं चौड़ाई चाहते

std::complex i(0, 1); 
std::cout << std::setw(10) << std::left << i; 

यह "(0,1)     " नहीं "(         0,1)"

मुद्रित चाहिए एक एकल स्ट्रिंग के रूप में पूरे उत्पादन के गठन तो यह लिखने उत्पादन सम्मान क्षेत्र चौड़ाई और अन्य स्वरूपण झंडे धारा पर सेट करके।

2

इस पैटर्न का एक प्राथमिक उद्देश्य मूल धारा के मैनिपुलेटर्स/झंडे को बनाए रखने से बचने और लौटने से पहले उन्हें रीसेट करने से बचाना है। Boost.IoStateSavers इसकी आवश्यकता को रोकता है, इसलिए मैं कहूंगा कि कहा लाइब्रेरी का उपयोग करना एक बेहतर अभ्यास होगा।

4

किसी अन्य प्रतिक्रिया में उद्धृत थ्रेडिंग कारण वास्तव में काम नहीं करेगा: स्ट्रिंग अभी भी स्ट्रीम बफर स्तर पर विभाजित हो सकती है क्योंकि ये ऑपरेशन एकाधिक धागे से बुलाए जाने पर परमाणु नहीं होते हैं।

  1. कुछ आउटपुट आप अस्थायी रूप से प्रारूप ध्वज सेटिंग में बदलाव के लिए:

    हालांकि, वहाँ दो कारणों से जो प्रासंगिक हैं। उदाहरण के लिए, आप यह सुनिश्चित करना चाहते हैं कि कुछ स्ट्रिंग हेक्स नोटेशन का उपयोग करके अन्य डीसी नोटेशन के लिए दिखाई दे और आप स्ट्रीम को मूल स्थिति में पुनर्स्थापित करना चाहते हैं।

  2. अधिक महत्वपूर्ण बात यह है कि आउटपुट के width() का अर्थ कम से कम स्वरूपण स्ट्रिंग को कम से कम वर्णित वर्णों की संख्या है। यदि आप आउटपुट ऑपरेटरों को आंतरिक रूप से किसी अन्य आउटपुट ऑपरेटर के लिए उपयोग करते हैं तो आप कई तत्वों वाली परिणामी संपूर्ण स्ट्रिंग के बजाय चौड़ाई पर कब्जा करने के लिए पहला तत्व बनायेंगे। उदाहरण के लिए, एक जटिल संख्या के लिए वास्तविक तत्व वास्तविक तत्व, अल्पविराम, और काल्पनिक तत्व के संयोजन के बजाय width() पर कब्जा करेगा।