如何在C++中编写ostreams的向量,它接受所有不同的输出流,如cout,ostringstream和ofstream

imt*_*990 4 c++ vector ostream c++11

我正在尝试实现一个记录器,它可以注册多个流,如ostringstream,ofstream等.我试图实现这样的功能

void register_stream(std::ostream& a);
Run Code Online (Sandbox Code Playgroud)

矢量如下

std::vector<std::ostream> streams;
Run Code Online (Sandbox Code Playgroud)

寄存器流和运算符重载如下

void logger::register_stream(std::ostream &a)`

{

    streams.push_back(a);

}

template <typename T>

void logger::operator<<(T const& value)

{

    for (auto stream : streams)

    {

        (stream) << value;

    }

}
Run Code Online (Sandbox Code Playgroud)

我正在尝试实现一个记录器,以便在单个操作员" <<"调用中写入所有已注册的流.

以下是调用代码:

std::ostringstream os;
    std::ofstream f;
    logger l;
    l.register_stream(f);
    l.register_stream(os);
    l << "log this";
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

C2280 :: std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)尝试引用已删除的函数

任何帮助将非常感激.

Max*_*kin 5

ostream做格式化和写入底层streambuf.因此,当您operator<<多次使用时,它会不必要地多次格式化相同的输入.更优化的方法是格式化一次,然后stream使用未格式化的输出函数将格式化的输出复制到多个底层s ostream::write.

具有std::ostream接口是很方便的,因此您可以将其传递给期望std::ostream接口的现有功能.

您基本上需要自定义streambuf实现.从头开始编写一个很好的学习经验,但是单调乏味且容易出错,因为streambuf界面有点难以理解和正确实现.请改用Boost Iostreams Library.

工作范例:

#include <boost/iostreams/stream.hpp>
#include <algorithm>
#include <iostream>
#include <vector>

struct MultiSink {
    using char_type = char;

    struct category
        : boost::iostreams::sink_tag
        , boost::iostreams::flushable_tag
    {};

    std::vector<std::ostream*> sinks_;

    std::streamsize write(char const* s, std::streamsize n) {
        for(auto sink : sinks_)
            sink->write(s, n);
        return n;
    }

    bool flush() {
        for(auto sink : sinks_)
            sink->flush();
        return true;
    }

    void add_sink(std::ostream& s) {
        sinks_.push_back(&s);
    }

    void remove_sink(std::ostream& s) {
        sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), &s), sinks_.end());
    }
};

int main() {
    MultiSink sink;
    boost::iostreams::stream<MultiSink> stream(sink);
    stream->add_sink(std::cout);
    stream->add_sink(std::cerr);

    stream << "Hello, world!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

请注意,代码假定已注册的流比多接收器更长.如果不是这种情况,则需要在多个接收器被销毁之前取消注册.