C++ 使用<&书信电报;运算符写入文件和cout

C++ 使用<&书信电报;运算符写入文件和cout,c++,file,operator-overloading,cout,C++,File,Operator Overloading,Cout,我想重载创建一个helper类和重载操作符来处理两个流的流。使用helper类,而不是试图重写重载的操作符的标准库实现,它只是将值写入文本文件,因为您的操作符重载的函数的左边是std::ostream&,右边是const std::string&。以下是调用函数的方式: fl要实现全流接口,您应该构建流缓冲区和流: #include <ostream> #include <sstream> #include <streambuf> #include <v

我想重载创建一个helper类和重载操作符来处理两个流的流。使用helper类,而不是试图重写重载的
操作符的标准库实现,它只是将值写入文本文件,因为您的操作符重载的函数的左边是
std::ostream&
,右边是
const std::string&
。以下是调用函数的方式:


fl要实现全流接口,您应该构建流缓冲区和流:

#include <ostream>
#include <sstream>
#include <streambuf>
#include <vector>

// BasicMultiStreamBuffer
// ============================================================================

template<class Char, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char> >
class BasicMultiStreamBuffer : public std::basic_stringbuf<Char, Traits, Allocator>
{
    // Types
    // =====

    private:
    typedef typename std::basic_stringbuf<Char, Traits> Base;

    public:
    typedef typename std::basic_streambuf<Char, Traits> buffer_type;
    typedef typename buffer_type::char_type char_type;
    typedef typename buffer_type::traits_type traits_type;
    typedef typename buffer_type::int_type int_type;
    typedef typename buffer_type::pos_type pos_type;
    typedef typename buffer_type::off_type off_type;

    private:
    typedef typename std::vector<buffer_type*> container_type;

    public:
    typedef typename container_type::size_type size_type;
    typedef typename container_type::value_type value_type;
    typedef typename container_type::reference reference;
    typedef typename container_type::const_reference const_reference;
    typedef typename container_type::iterator iterator;
    typedef typename container_type::const_iterator const_iterator;


    // Construction/Destructiion
    // =========================

    public:
    BasicMultiStreamBuffer()
    {}

    BasicMultiStreamBuffer(buffer_type* a) {
        if(a) {
            m_buffers.reserve(1);
            m_buffers.push_back(a);
        }
    }

    template <typename Iterator>
    BasicMultiStreamBuffer(Iterator first, Iterator last)
    :   m_buffers(first, last)
    {}

    ~BasicMultiStreamBuffer() {
        sync();
    }


    private:
    BasicMultiStreamBuffer(BasicMultiStreamBuffer const&); // No Copy.
    BasicMultiStreamBuffer& operator=(BasicMultiStreamBuffer const&); // No Copy.


    // Capacity
    // ========

    public:
    bool empty() const { return m_buffers.empty(); }
    size_type size() const { return m_buffers.size(); }


    // Iterator
    // ========

    public:
    iterator begin() { return m_buffers.begin(); }
    const_iterator begin() const { return m_buffers.end(); }
    iterator end() { return m_buffers.end(); }
    const_iterator end() const { return m_buffers.end(); }


    // Modifiers
    // =========

    public:
    void insert(buffer_type* buffer) {
        if(buffer) m_buffers.push_back(buffer);
    }

    void erase(buffer_type* buffer) {
        iterator pos = this->begin();
        for( ; pos != this->end(); ++pos) {
            if(*pos == buffer) {
                m_buffers.erase(pos);
                break;
            }
        }
    }


    // Synchronization
    // ===============

    protected:
    virtual int sync() {
        int result = 0;
        if( ! m_buffers.empty()) {
            char_type* p = this->pbase();
            std::streamsize n = this->pptr() - p;
            if(n) {
                const_iterator pos = m_buffers.begin();
                for( ; pos != m_buffers.end(); ++pos) {
                    std::streamoff offset = 0;
                    while(offset < n) {
                        int k = (*pos)->sputn(p + offset, n - offset);
                        if(0 <= k) offset += k;
                        else {
                            result = -1;
                            break;
                        }
                    }
                    if((*pos)->pubsync() == -1) result = -1;
                }
                this->setp(this->pbase(), this->epptr());
            }
        }
        if(Base::sync() == -1) result = -1;
        return result;
    }

    private:
    container_type m_buffers;
};

typedef BasicMultiStreamBuffer<char> OStreamBuffers;


// BasicMultiStream
// ============================================================================

template<class Char, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char> >
class BasicMultiStream : public std::basic_ostream<Char, Traits>
{
    // Types
    // =====

    private:
    typedef std::basic_ostream<Char, Traits> Base;

    public:
    typedef BasicMultiStreamBuffer<Char, Traits, Allocator> multi_buffer;
    typedef std::basic_ostream<Char, Traits> stream_type;

    typedef typename multi_buffer::buffer_type buffer_type;
    typedef typename multi_buffer::char_type char_type;
    typedef typename multi_buffer::traits_type traits_type;
    typedef typename multi_buffer::int_type int_type;
    typedef typename multi_buffer::pos_type pos_type;
    typedef typename multi_buffer::off_type off_type;

    typedef typename multi_buffer::size_type size_type;
    typedef typename multi_buffer::value_type value_type;
    typedef typename multi_buffer::reference reference;
    typedef typename multi_buffer::const_reference const_reference;
    typedef typename multi_buffer::iterator iterator;
    typedef typename multi_buffer::const_iterator const_iterator;


    // Construction
    // ============

    public:
    BasicMultiStream()
    :   Base(&m_buffer)
    {}
    BasicMultiStream(stream_type& stream)
    :   Base(&m_buffer), m_buffer(stream.rdbuf())
    {}

    template <typename StreamIterator>
    BasicMultiStream(StreamIterator& first, StreamIterator& last)
    :   Base(&m_buffer)
    {
        while(first != last) insert(*first++);
    }

    private:
    BasicMultiStream(const BasicMultiStream&); // No copy.
    const BasicMultiStream& operator = (const BasicMultiStream&); // No copy.

    // Capacity
    // ========

    public:
    bool empty() const { return m_buffer.empty(); }
    size_type size() const { return m_buffer.size(); }


    // Iterator
    // ========

    public:
    iterator begin() { return m_buffer.begin(); }
    const_iterator begin() const { return m_buffer.end(); }
    iterator end() { return m_buffer.end(); }
    const_iterator end() const { return m_buffer.end(); }


    // Modifiers
    // =========

    public:
    void insert(stream_type& stream) { m_buffer.insert(stream.rdbuf()); }
    void erase(stream_type& stream) { m_buffer.erase(stream.rdbuf()); }

    private:
    multi_buffer m_buffer;
};

typedef BasicMultiStream<char> MultiStream;


// Test
// =============================================================================

#include <iostream>
int main() {
    MultiStream out;
    out.insert(std::cout);
    out.insert(std::clog);
    out << "Hello\n";
}
#包括
#包括
#包括
#包括
//基本多流缓冲器
// ============================================================================
模板
类BasicMultiStreamBuffer:public std::basic_stringbuf
{
//类型
// =====
私人:
typedef typename std::basic_stringbuf Base;
公众:
typedef typename std::basic_streambuf buffer_type;
typedef typename buffer_type::char_type char_type;
typedef typename buffer_type::traits_type traits_type;
typedef typename buffer_type::int_type int_type;
typedef typename buffer_type::pos_type pos_type;
typedef typename buffer_type::off_type off_type;
私人:
typedef typename std::vector container_type;
公众:
typedef typename容器\类型::大小\类型大小\类型;
typedef typename容器类型::值类型值类型;
typedef typename容器\ u type::reference引用;
typedef typename container_type::const_reference const_reference;
typedef typename容器_type::迭代器迭代器;
typedef typename容器类型::常量迭代器常量迭代器;
//建造/破坏
// =========================
公众:
BasicMultiStreamBuffer()
{}
基本多流缓冲区(缓冲区类型*a){
如果(a){
m_.储备(1);
m_缓冲器。推回(a);
}
}
模板
BasicMultiStreamBuffer(迭代器优先,迭代器最后)
:m_缓冲区(第一个、最后一个)
{}
~BasicMultiStreamBuffer(){
sync();
}
私人:
BasicMultiStreamBuffer(BasicMultiStreamBuffer常量&);//无副本。
BasicMultiStreamBuffer&运算符=(BasicMultiStreamBuffer常量&);//无副本。
//容量
// ========
公众:
bool empty()常量{return m_buffers.empty();}
size_type size()常量{return m_buffers.size();}
//迭代器
// ========
公众:
迭代器begin(){返回m_缓冲区。begin();}
常量迭代器begin()常量{return m_buffers.end();}
迭代器end(){return m_buffers.end();}
const_迭代器end()const{return m_buffers.end();}
//修饰语
// =========
公众:
无效插入(缓冲区类型*缓冲区){
if(buffer)m_buffers.push_back(buffer);
}
无效擦除(缓冲区类型*缓冲区){
迭代器pos=this->begin();
对于(;pos!=此->结束();++pos){
如果(*pos==缓冲区){
m_缓冲区擦除(pos);
打破
}
}
}
//同步
// ===============
受保护的:
虚拟整数同步(){
int结果=0;
如果(!m_buffers.empty()){
char_type*p=this->pbase();
std::streamsize n=this->pptr()-p;
如果(n){
常量迭代器pos=m_buffers.begin();
对于(;pos!=m_buffers.end();++pos){
标准::流量偏移=0;
while(偏移量sputn(p+偏移,n-偏移);
如果(0 pubsync()=-1)结果=-1;
}
this->setp(this->pbase(),this->epptr());
}
}
如果(Base::sync()==-1)结果=-1;
返回结果;
}
私人:
容器式m_缓冲器;
};
typedef BasicMultiStreamBuffer-OStreamBuffers;
//基本多流
// ============================================================================
模板
类BasicMultiStream:public std::basic_ostream
{
//类型
// =====
私人:
typedef标准::基本的团队基础;
公众:
typedef BasicMultiStreamBuffer multi_buffer;
typedef std::基本流类型;
typedef typename multi_buffer::buffer_type buffer_type;
typedef typename multi_buffer::char_type char_type;
typedef typename multi_buffer::traits_type traits_type;
typedef typename多_缓冲区::int_type int_type;
typedef typename多_缓冲区::pos_type pos_type;
typedef typename multi_buffer::off_type off_type;
typedef typename multi_buffer::size_type size_type;
typedef typename multi_buffer::value_type value_type;
typedef typename multi_buffer::reference;
typedef typename multi_buffer::const_reference const_reference;
typedef typename多_缓冲区::迭代器迭代器;
typedef typename multi_buffer::const_iterator const_iterator;
//建筑
// ============
公众:
BasicMultiStream()
:基本(&m_缓冲区)
{}
基本多流(流类型和流)
:Base(&m_buffer),m_buffer(stream.rdbuf())
{}
模板
BasicMultiStream(StreamIterator&first、StreamIterator&last)
:基本(&m_缓冲区)
{
while(first!=last)insert(*first++);
}
私人:
BasicMultiStream(const BasicMultiStream&);//无副本。
const BasicMultiStream&运算符=(const BasicMultiStream&);//无副本。
//容量
// ========
公众:
bool empty()常量{return m_buffer.empty();}
size_type size()常量{return m_buffer.size();}
//迭代器
// ========
公众:
迭代器begin(){返回m_buffer.begin();}
常量迭代器begin()常量{return m_buffer.end();}
迭代器end(){return m_buffer.end();}
const_迭代器end()const{return m_buffer.end();}
//修饰语
// =========
公众:
无效的
#include <iostream>
#include <fstream>

struct MyStreamingHelper
{
    MyStreamingHelper(std::ostream& out1,
                      std::ostream& out2) : out1_(out1), out2_(out2) {}
    std::ostream& out1_;
    std::ostream& out2_;
};

template <typename T>
MyStreamingHelper& operator<<(MyStreamingHelper& h, T const& t)
{
   h.out1_ << t;
   h.out2_ << t;
   return h;
}

MyStreamingHelper& operator<<(MyStreamingHelper& h, std::ostream&(*f)(std::ostream&))
{
   h.out1_ << f;
   h.out2_ << f;
   return h;
}

int main()
{
   std::ofstream fl;
   fl.open("test.txt");
   MyStreamingHelper h(fl, std::cout);
   h << "!!!Hello World!!!" << std::endl;
   return 0;
}
#include <ostream>
#include <sstream>
#include <streambuf>
#include <vector>

// BasicMultiStreamBuffer
// ============================================================================

template<class Char, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char> >
class BasicMultiStreamBuffer : public std::basic_stringbuf<Char, Traits, Allocator>
{
    // Types
    // =====

    private:
    typedef typename std::basic_stringbuf<Char, Traits> Base;

    public:
    typedef typename std::basic_streambuf<Char, Traits> buffer_type;
    typedef typename buffer_type::char_type char_type;
    typedef typename buffer_type::traits_type traits_type;
    typedef typename buffer_type::int_type int_type;
    typedef typename buffer_type::pos_type pos_type;
    typedef typename buffer_type::off_type off_type;

    private:
    typedef typename std::vector<buffer_type*> container_type;

    public:
    typedef typename container_type::size_type size_type;
    typedef typename container_type::value_type value_type;
    typedef typename container_type::reference reference;
    typedef typename container_type::const_reference const_reference;
    typedef typename container_type::iterator iterator;
    typedef typename container_type::const_iterator const_iterator;


    // Construction/Destructiion
    // =========================

    public:
    BasicMultiStreamBuffer()
    {}

    BasicMultiStreamBuffer(buffer_type* a) {
        if(a) {
            m_buffers.reserve(1);
            m_buffers.push_back(a);
        }
    }

    template <typename Iterator>
    BasicMultiStreamBuffer(Iterator first, Iterator last)
    :   m_buffers(first, last)
    {}

    ~BasicMultiStreamBuffer() {
        sync();
    }


    private:
    BasicMultiStreamBuffer(BasicMultiStreamBuffer const&); // No Copy.
    BasicMultiStreamBuffer& operator=(BasicMultiStreamBuffer const&); // No Copy.


    // Capacity
    // ========

    public:
    bool empty() const { return m_buffers.empty(); }
    size_type size() const { return m_buffers.size(); }


    // Iterator
    // ========

    public:
    iterator begin() { return m_buffers.begin(); }
    const_iterator begin() const { return m_buffers.end(); }
    iterator end() { return m_buffers.end(); }
    const_iterator end() const { return m_buffers.end(); }


    // Modifiers
    // =========

    public:
    void insert(buffer_type* buffer) {
        if(buffer) m_buffers.push_back(buffer);
    }

    void erase(buffer_type* buffer) {
        iterator pos = this->begin();
        for( ; pos != this->end(); ++pos) {
            if(*pos == buffer) {
                m_buffers.erase(pos);
                break;
            }
        }
    }


    // Synchronization
    // ===============

    protected:
    virtual int sync() {
        int result = 0;
        if( ! m_buffers.empty()) {
            char_type* p = this->pbase();
            std::streamsize n = this->pptr() - p;
            if(n) {
                const_iterator pos = m_buffers.begin();
                for( ; pos != m_buffers.end(); ++pos) {
                    std::streamoff offset = 0;
                    while(offset < n) {
                        int k = (*pos)->sputn(p + offset, n - offset);
                        if(0 <= k) offset += k;
                        else {
                            result = -1;
                            break;
                        }
                    }
                    if((*pos)->pubsync() == -1) result = -1;
                }
                this->setp(this->pbase(), this->epptr());
            }
        }
        if(Base::sync() == -1) result = -1;
        return result;
    }

    private:
    container_type m_buffers;
};

typedef BasicMultiStreamBuffer<char> OStreamBuffers;


// BasicMultiStream
// ============================================================================

template<class Char, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char> >
class BasicMultiStream : public std::basic_ostream<Char, Traits>
{
    // Types
    // =====

    private:
    typedef std::basic_ostream<Char, Traits> Base;

    public:
    typedef BasicMultiStreamBuffer<Char, Traits, Allocator> multi_buffer;
    typedef std::basic_ostream<Char, Traits> stream_type;

    typedef typename multi_buffer::buffer_type buffer_type;
    typedef typename multi_buffer::char_type char_type;
    typedef typename multi_buffer::traits_type traits_type;
    typedef typename multi_buffer::int_type int_type;
    typedef typename multi_buffer::pos_type pos_type;
    typedef typename multi_buffer::off_type off_type;

    typedef typename multi_buffer::size_type size_type;
    typedef typename multi_buffer::value_type value_type;
    typedef typename multi_buffer::reference reference;
    typedef typename multi_buffer::const_reference const_reference;
    typedef typename multi_buffer::iterator iterator;
    typedef typename multi_buffer::const_iterator const_iterator;


    // Construction
    // ============

    public:
    BasicMultiStream()
    :   Base(&m_buffer)
    {}
    BasicMultiStream(stream_type& stream)
    :   Base(&m_buffer), m_buffer(stream.rdbuf())
    {}

    template <typename StreamIterator>
    BasicMultiStream(StreamIterator& first, StreamIterator& last)
    :   Base(&m_buffer)
    {
        while(first != last) insert(*first++);
    }

    private:
    BasicMultiStream(const BasicMultiStream&); // No copy.
    const BasicMultiStream& operator = (const BasicMultiStream&); // No copy.

    // Capacity
    // ========

    public:
    bool empty() const { return m_buffer.empty(); }
    size_type size() const { return m_buffer.size(); }


    // Iterator
    // ========

    public:
    iterator begin() { return m_buffer.begin(); }
    const_iterator begin() const { return m_buffer.end(); }
    iterator end() { return m_buffer.end(); }
    const_iterator end() const { return m_buffer.end(); }


    // Modifiers
    // =========

    public:
    void insert(stream_type& stream) { m_buffer.insert(stream.rdbuf()); }
    void erase(stream_type& stream) { m_buffer.erase(stream.rdbuf()); }

    private:
    multi_buffer m_buffer;
};

typedef BasicMultiStream<char> MultiStream;


// Test
// =============================================================================

#include <iostream>
int main() {
    MultiStream out;
    out.insert(std::cout);
    out.insert(std::clog);
    out << "Hello\n";
}
#include <iostream>
#include <fstream>
#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>

typedef boost::iostreams::tee_device<std::ostream, std::ostream> teedev;
typedef boost::iostreams::stream<teedev, std::char_traits<typename std::ostream::char_type>, std::allocator< typename std::ostream::char_type > > tee_stream;

int main(int argc, char* argv[])
{
    std::ofstream of;
    of.open( "test.txt" );

    teedev td( of, std::cout );
    tee_stream ts(td);

    ts << "!!!Hello World!!!" << std::endl;

    return 0;
}
class LoggingStreambuf : public std::streambuf
{
    std::streambuf* myPrinciple;
    std::ostream*   myOwner;
    std::filebuf    myLogging;
protected:
    int overflow( int ch ) override
    {
        myLogging->sputc( ch );
        return myPrinciple->sputc( ch );
    }
public:
    LoggingStreambuf( std::streambuf* principal, std::string const& logFileName )
        : myPrinciple( principal )
        , myOwner( nullptr )
        , myLogging( logFileName )
    {
    }

    LoggingStreambuf( std::ostream& principal, std::string const& logFileName )
        : myPrinciple( principal.rdbuf() )
        , myOwner( &principal )
        , myLogging( logFileName )
    {
        myOwner.rdbuf( this );
    }

    ~LoggingStreambuf()
    {
        if ( myOwner != nullptr ) {
            myOwner.rdbuf( myPrinciple );
        }
    }
};
LoggingStreambuf logger( std::cout, "logfile.txt" );
//  And output to std::cout as usual...