gpt4 book ai didi

c++ - 如何在语句结束时触发操作?

转载 作者:行者123 更新时间:2023-11-30 03:49:23 29 4
gpt4 key购买 nike

假设我想创建一个流,它会在语句末尾执行一个操作,这样

myStream << "Hello, " << "World!";

将打印“Hello, World!\n”一次。不是“Hello,\nWorld!\n”也不是“Hello, World!”,而是“Hello, World\n”,就好像;会触发附加 \n并刷新缓冲区。

这样做的基本原理是一个写入 stdout 的流类和一个日志文件,日志文件条目具有特定的前缀和后缀。

例如,如果我的目标是 HTML,我需要以下代码:

myStream << "Hello, " << "World!";
myStream << "Good bye, " << "cruel World!";

像这样打印:

<p>Hello, World!</p>
<p>Good bye, cruel World!</p>

并且是这样的:

<p>Hello, </p><p>World!</p>
<p>Good bye, </p><p>cruel World!</p>

现在,如果我执行 LogStream有点像这样:

LogStream & LogStream::operator<<( const std::string & text );

我无法区分 <<在语句的开头/结尾的语句中间。

如果我实现 LogStream有点像这样:

LogStream LogStream::operator<<( const std::string & text );

并尝试在析构函数中修改输入,我会在代码块的末尾同时获得多个析构函数。

最后,我可以实现我的要求 endl在每个语句的末尾,但我不想打扰调用者这样做的必要性。

因此问题来了:如何以对调用者透明的方式实现这样的流?

最佳答案

我曾为自定义日志系统实现过类似的功能。我创建了一个缓冲输入的类,然后它的析构函数将缓冲区刷新到我的日志文件中。

例如:

#include <iostream>
#include <sstream>
#include <string>

class LogStream
{
private:
std::stringstream m_ss;

void flush()
{
const std::string &s = m_ss.str();
if (s.length() > 0)
{
std::cout << s << std::endl;
logfile << "<p>" << s << "</p>" << std::endl;
}
}

public:
LogStream() {}

~LogStream()
{
flush();
}

template <typename T>
LogStream& operator<<(const T &t)
{
m_ss << t;
return *this;
}

template <typename T>
LogStream& operator<<( std::ostream& (*fp)(std::ostream&) )
{
// TODO: if fp is std::endl, write to log and reset m_ss
fp(m_ss);
return *this;
}

void WriteToLogAndReset()
{
flush();
m_ss.str(std::string());
m_ss.clear();
}
};

对于在最终 ; 上刷新的单个语句,每条消息都将使用该类的一个新实例:

LogStream() << "Hello, " << "World!";
LogStream() << "Good bye, " << "cruel World!";

要允许多个语句写入单个消息,请创建对象并在最后一个语句完成之前不要让它超出范围:

{
LogStream myStream;
myStream << "Hello, ";
myStream << "World!";
}

{
LogStream myStream;
myStream << "Good bye, ";
myStream << "cruel World!";
}

要为多条消息重用现有实例,请告诉它在每条消息之间刷新和重置:

{
LogStream myStream;
myStream << "Hello, " << "World!";
myStream.WriteToLogAndReset();
myStream << "Good bye, " << "cruel World!";
}

我喜欢这种方法,因为它使调用者可以更灵活地决定何时准备好将每条消息写入日志文件。例如,我使用它来将多个值发送到单个日志消息,其中这些值是从决策代码分支中获取的。这样,我可以流式传输一些值、做出一些决定、流式传输更多值等,然后将完成的消息发送到日志。

关于c++ - 如何在语句结束时触发操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32595335/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com