#include <iostream>
#include <streambuf>
#include <fstream>
//------------------------------------------------------------------------------
template<classcharT,classtraits=std::char_traits<charT>>classbasic_teebuf:publicstd::basic_streambuf<charT,traits>{public:typedefcharTchar_type;typedeftypenametraits::int_typeint_type;typedeftypenametraits::pos_typepos_type;typedeftypenametraits::off_typeoff_type;typedeftraitstraits_type;typedefstd::basic_streambuf<charT,traits>streambuf_type;private:streambuf_type*m_sbuf1;streambuf_type*m_sbuf2;char_type*m_buffer;enum{BUFFER_SIZE=4096/sizeof(char_type)};public:basic_teebuf(streambuf_type*sbuf1,streambuf_type*sbuf2):m_sbuf1(sbuf1),m_sbuf2(sbuf2),m_buffer(newchar_type[BUFFER_SIZE]){setp(m_buffer,m_buffer+BUFFER_SIZE);}//constructor
~basic_teebuf(){this->pubsync();delete[]m_buffer;}//destructor
protected:virtualint_typeoverflow(int_typec=traits_type::eof()){// empty our buffer into m_sbuf1 and m_sbuf2
std::streamsizen=static_cast<std::streamsize>(this->pptr()-this->pbase());std::streamsizesize1=m_sbuf1->sputn(this->pbase(),n);std::streamsizesize2=m_sbuf2->sputn(this->pbase(),n);if(size1!=n||size2!=n)returntraits_type::eof();// reset our buffer
setp(m_buffer,m_buffer+BUFFER_SIZE);// write the passed character if necessary
if(!traits_type::eq_int_type(c,traits_type::eof())){traits_type::assign(*this->pptr(),traits_type::to_char_type(c));this->pbump(1);}//if
returntraits_type::not_eof(c);}//overflow
virtualintsync(){// flush our buffer into m_sbuf1 and m_sbuf2
int_typec=this->overflow(traits_type::eof());// checking return for eof.
if(traits_type::eq_int_type(c,traits_type::eof()))return-1;// flush m_sbuf1 and m_sbuf2
if(m_sbuf1->pubsync()==-1||m_sbuf2->pubsync()==-1)return-1;return0;}//sync
};//basic_teebuf
typedefbasic_teebuf<char>teebuf;typedefbasic_teebuf<wchar_t>wteebuf;//------------------------------------------------------------------------------
template<classcharT,classtraits=std::char_traits<charT>>structscoped_basic_streambuf_assignment{typedefstd::basic_ios<charT,traits>stream_type;typedefstd::basic_streambuf<charT,traits>streambuf_type;stream_type&m_s;streambuf_type*m_orig_sb;scoped_basic_streambuf_assignment(stream_type&s,streambuf_type*new_sb):m_s(s){m_orig_sb=m_s.rdbuf(new_sb);}//constructor
~scoped_basic_streambuf_assignment(){m_s.rdbuf(m_orig_sb);}//destructor
};//scoped_streambuf_assignment
typedefscoped_basic_streambuf_assignment<char>scoped_streambuf_assignment;typedefscoped_basic_streambuf_assignment<wchar_t>scoped_wstreambuf_assignment;//------------------------------------------------------------------------------
intmain(){std::ofstreamfile("data.txt");std::ofstreamfile2("data2.txt");// tbuf will write to both file and cout
teebuftbuf(file.rdbuf(),std::cout.rdbuf());// tbuf2 will write to both tbuf and file2
teebuftbuf2(file2.rdbuf(),&tbuf);// replace cout's streambuf with tbuf2
scoped_streambuf_assignmentssa(std::cout,&tbuf2);std::cout<<"Hello World"<<std::endl;return0;}//main
近期评论