实现完整的流接口,您应该构建一个流缓冲区和一个流:
#include <ostream>
#include <sstream>
#include <streambuf>
#include <vector>
template<class Char, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char> >
class BasicMultiStreamBuffer : public std::basic_stringbuf<Char, Traits, Allocator>
{
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;
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&);
BasicMultiStreamBuffer& operator=(BasicMultiStreamBuffer const&);
public:
bool empty() const { return m_buffers.empty(); }
size_type size() const { return m_buffers.size(); }
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(); }
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;
}
}
}
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;
template<class Char, class Traits = std::char_traits<Char>, class Allocator = std::allocator<Char> >
class BasicMultiStream : public std::basic_ostream<Char, Traits>
{
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;
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&);
const BasicMultiStream& operator = (const BasicMultiStream&);
public:
bool empty() const { return m_buffer.empty(); }
size_type size() const { return m_buffer.size(); }
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(); }
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;
#include <iostream>
int main() {
MultiStream out;
out.insert(std::cout);
out.insert(std::clog);
out << "Hello\n";
}
在这里,输出被缓存在字符串流缓冲区中,并同步到目标流。
streambuffer
的ostream
。没有标准的这样的流。 - Deduplicator