2011-12-14 11 views
6

मैं कक्षा MyCout को लागू करना चाहते हैं, जो स्वत: endl की संभावना प्रदान कर सकते हैं, यानी यह कोडmycout स्वचालित endl

MyCout mycout; 
mycout<<1<<2<<3; 

आउटपुट

123 
//empty line here 

यह इस तरह कार्यक्षमता के साथ वर्ग को लागू करना संभव है?


अद्यतन: Soulutions की तरह नहीं होना चाहिए कि MyCout()<<1<<2<<3; यानी वे अस्थायी वस्तु

+0

बेशक यह संभव है, क्या आपके पास अपने स्वयं के वर्ग और ऑपरेटर ओवरलोडिंग के बारे में एक और अधिक विशिष्ट सवाल है? – TJD

+0

आप ऐसा क्यों करना चाहते हैं? –

+0

यह एक दिलचस्प समस्या है। जैसा कि मैं समझता हूं कि अंतराल फ्लशिंग के साथ जुड़ा हुआ है। इस बात का जिक्र नहीं है कि ऑपरेटर ओवरलोडिंग विधि को कुछ पता होना होगा कि अंतराल कहां से संबंधित है, यह जानने के बाद क्या होता है। –

उत्तर

2

यह केवल Rob's answer का एक प्रकार है कि ढेर का उपयोग नहीं करता है। यह एक बड़ा बदलाव है कि मैं सिर्फ

struct MyCout { 
    MyCout(std::ostream& os = std::cout) : os(os) {} 
    struct A { 
    A(std::ostream& r) : os(r), live(true) {} 
    A(A& r) : os(r.os), live(true) {r.live=false;} 
    ~A() { if(live) {os << std::endl;} } 
    std::ostream& os; 
    bool live; 
    }; 
    std::ostream& os; 
}; 

template <class T> 
MyCout::A& operator<<(MyCout::A& a, const T& t) { 
    a->os << t; 
    return a; 
} 

template<class T> 
MyCout::A operator<<(MyCout& m, const T& t) { return MyCout::A(os) << t; } 

int main() { 
    MyCout mycout; 
    mycout << 1 << 2 << 3; 
    mycout << 3 << 4 << 5; 
    MyCout mycerr(std::cerr); 
    mycerr << 6 << "Hello, world" << "!"; 
} 
+0

क्या आप निश्चित हो सकते हैं कि कॉपी ऑपरेशन 'ऑपरेटर << (MyCout &, const T &)' से वापसी में नहीं होगा? –

+1

@Rob: नहीं, लेकिन अगर मैंने इसे सही किया है, तो यह प्रोग्राम के व्यवहार को नहीं बदलेगा। मैं एक चालक कन्स्ट्रक्टर अनुकरण करने के लिए 'बूल लाइव' का उपयोग करता हूं। –

8

बनाते समय धारा फ्लश और एक नई पंक्ति मुद्रित करने के लिए एक अस्थायी वस्तु का नाशक उपयोग कर सकते हैं बिना होना चाहिए। क्यूटी डीबग सिस्टम यह करता है, और this answer वर्णन करता है कि यह कैसे करें।

+0

लिखना नहीं है, मैं भी यही सोच रहा था। आंतरिक परिचालनों के लिए चलने वाले अर्थशास्त्र के साथ। –

+0

हालांकि आप केवल एक ऑब्जेक्ट स्टेटमेंट के लिए प्रत्येक ऑब्जेक्ट का उपयोग कर सकते हैं, जो कि बेहद उपोष्णकटिबंधीय लगता है। –

+0

@Autopulated, हाँ, मुझे इस संस्करण के बारे में पता है, लेकिन मैंने लिखा है कि इसे निम्नलिखित तरीके से देखना चाहिए: 'MyCout mycout; mycout << ... 'यानी अस्थायी वस्तु समाधान नहीं है – eXXXXXXXXXXX2

7

सी ++ 11 में निम्नलिखित काम करता है:

#include <iostream> 

struct myout_base { }; 
struct myout 
{ 
    bool alive; 
    myout() : alive(true) { } 
    myout(myout && rhs) : alive(true) { rhs.alive = false; } 
    myout(myout const &) = delete; 
    ~myout() { if (alive) std::cout << std::endl; } 
}; 

template <typename T> 
myout operator<<(myout && o, T const & x) 
{ 
    std::cout << x; 
    return std::move(o); 
} 

template <typename T> 
myout operator<<(myout_base &, T const & x) 
{ 
    return std::move(myout() << x); 
} 

myout_base m_out; // like the global std::cout 

int main() 
{ 
    m_out << 1 << 2 << 3; 
} 

अधिक काम के साथ, आप वास्तविक उत्पादन धारा के लिए एक संदर्भ जोड़ सकते हैं।

+0

अब यह एक साफ समाधान है। – James

+0

केवल स्पष्ट सी ++ का उपयोग करना संभव है?) – eXXXXXXXXXXX2

+4

हां। मैं * केवल स्पष्ट सी ++ का उपयोग कर रहा हूं :-) –

1

आप सी ++ 11 सुविधाओं से बचने के लिए की जरूरत है:

#include <iostream> 
#include <sstream> 
#include <memory> 

struct MyCout { 
    MyCout(std::ostream& os = std::cout) : os(os) {} 
    struct A { 
    A(std::ostream& os) : os(os) {} 
    A() : os(os) {} 
    ~A() { os << std::endl; } 
    std::ostream& os; 
    }; 
    std::ostream& os; 
}; 

template <class T> 
const std::auto_ptr<MyCout::A>& 
operator<<(const std::auto_ptr<MyCout::A>& a, const T& t) { 
    a->os << t; 
    return a; 
} 

template<class T> 
const std::auto_ptr<MyCout::A> 
operator<<(MyCout& m, const T& t) { 
    std::auto_ptr<MyCout::A> p(new MyCout::A(m.os)); 
    p << t; 
    return p; 
} 

int main() { 
    MyCout mycout; 
    mycout << 1 << 2 << 3; 
    mycout << 3 << 4 << 5; 
    MyCout mycerr(std::cerr); 
    mycerr << 6 << "Hello, world" << "!"; 
} 
+0

हां, बस एक आंतरिक वर्ग बनाएं और इसे प्रारंभिक << ऑपरेटर के संदर्भ के बजाय मूल्य से वापस कर दें, फिर उस ऑब्जेक्ट के विनाशक पर फ्लश/एंडल करें। ऑटो आपके लिए अस्थायी वस्तु बनाता है। –

+0

@ रोब: यह वही है जो मैं करता हूं, सिवाय इसके कि मैं यह देखने के लिए एक बूल का उपयोग करूंगा कि यह आवंटक को मारने के बजाय जीवित है या नहीं। –

+0

@ebyrob: मूल्य से वापस नहीं आ सकता है, क्योंकि यह एक प्रतिलिपि बना सकता है, और फिर अस्थायी को हटा सकता है, जिससे अतिरिक्त फ्लश हो सकता है। –

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