我正在尝试实现一个记录器,它可以注册到多个流,如 ostringstream、ofstream 等。我试图实现这样的功能
void register_stream(std::ostream& a);
载体如下
std::vector<std::ostream> streams;
寄存器流和运算符重载如下
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;
}
}
我正在尝试实现一个记录器,以在单个运算符“<<
”调用上写入所有已注册的流。
调用代码如下:
std::ostringstream os;
std::ofstream f;
logger l;
l.register_stream(f);
l.register_stream(os);
l << "log this";
我收到一个错误:
C2280:
std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)
: attempting to reference a deleted function
如有任何帮助,我们将不胜感激。
最佳答案
ostream
格式化和写入底层 streambuf
.这样当你使用 operator<<
多次不必要地多次格式化相同的输入。更优化的方法是格式化一次,然后将格式化后的输出复制到多个底层 stream
s 使用无格式输出函数 ostream::write
.
方便有std::ostream
接口(interface),以便您可以将其传递给期望 std::ostream
的现有函数界面。
您基本上需要一个自定义 streambuf
执行。从头开始编写一个是很好的学习经验,但乏味且容易出错,因为 streambuf
interface有点难以理解和正确实现。使用 The 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;
}
请注意,代码假定已注册流的生命周期超过多接收器。如果不是这种情况,您需要在销毁之前从多接收器注销流。
关于c++ - 如何在 C++ 中编写 ofstream vector ,它接收所有不同的输出流,如 cout、字符串流和 ofstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52277862/