C++ 使用<&书信电报;运算符写入文件和cout
我想重载创建一个helper类和重载操作符来处理两个流的流。使用helper类,而不是试图重写重载的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
操作符的标准库实现,它只是将值写入文本文件,因为您的操作符重载的函数的左边是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...