提问人:ZKlack 提问时间:10/4/2022 更新时间:10/4/2022 访问量:378
是否有空流?可选打印
is there a null stream? optional printing
问:
我使用像这样的函数
void doStuff(type thing, bool print = false, std::ostream& S = std::cout)
{
thing++;
if(print)
S << "new thing: " << thing << '\n';
}
这样我就可以使用相同的函数并决定调用是否希望它打印正在发生的事情的文档,以及如果我希望我可以在单独的流上打印它 - 我不知道我是否可以用 std::ostream 做到这一点-
我现在相信这样做会更好
void doStuff(type thing, std::ostream& S = NULL)
{
thing++;
if(S)
S << "new thing: " << thing << '\n';
}
但这不起作用,因为 std::ostream 不接受 NULL
问题:
- 是否有某种流类型的常量停止 if 条件?
- 我是否可以使用更灵活地接受字符串流和文件流等流的不同类型的流?
-有没有更好的方法来处理灵活的文档?
答:
0赞
Jude Davis
10/4/2022
#1
不要使用 ofstream 引用,而是使用指针,以便可以接受 .无法传递 NULL 的原因是引用无法引用,因为它可能会导致危险的未定义行为,如核心转储、段错误、磁盘重新格式化等。nullptr
NULL
执行以下操作:
void doStuff(type thing, std::ostream* S = nullptr)
{
thing++;
if(S != nullptr)
(*S) << "new thing: " << thing << '\n';
}
这样更安全一些,可以接受 .nullptr
总的来说,如果您只是输出到文件或控制台,ofstream 似乎是您的最佳选择。在灵活的文档方面,我这样做真的没有问题。我可能只有一个日志记录类,并用它来执行警告、信息日志、保存到文件等。
评论
2赞
πάντα ῥεῖ
10/4/2022
在较大的代码库中,这往往会变得乏味。我更喜欢包装接口,这样任何客户端代码都不需要知道或关心。std::ostream
5赞
francesco
10/4/2022
#2
可以使用 boost::iostream
库的 Null 接收器。
下面是一个工作示例:
#include <iostream>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/null.hpp>
boost::iostreams::stream<boost::iostreams::null_sink> nullstream{boost::iostreams::null_sink()};
void print_to_stream(std::ostream& s = nullstream)
{
s << "hello" << std::endl;
}
int main()
{
std::cout << "calling print_to_stream with s = std::cout" << std::endl;
print_to_stream(std::cout);
std::cout << "calling print_to_stream without argument" << std::endl;
print_to_stream();
return 0;
}
您可能希望将变量隐藏在某些命名空间或类中。nullstream
评论
0赞
francesco
10/5/2022
嗨,@ZKlack,如果这个或其他答案适合您的问题,您可以考虑接受它。没有这方面的义务。
0赞
ZKlack
10/10/2022
谢谢,我是这个网站的新手,你的回答正是我想做的,也是最合适的。当我有时间再次感谢时,我会阅读有关提升库的信息:)<3
3赞
A M
10/4/2022
#3
编写自己的流并不难,可以在好书中找到。
我为您创建了一个“NULL”流类。
请看下面非常简单的例子。
#include <iostream>
// This is a stream which does not output anything
class NullStream : public std::ostream
{
// streambuffer doing nothing
class NullBuffer : public std::streambuf
{
public:
int overflow(int c) noexcept override { return c; }
} nullBuffer;
public:
#pragma warning(suppress: 26455)
NullStream() : std::ostream(&nullBuffer) {}
NullStream(const NullStream&) = delete;
NullStream& operator=(const NullStream&) = delete;
};
// Define a global null stream
NullStream nout;
void doStuff(int& i, std::ostream& stream = nout)
{
i++;
stream << i << '\n';
}
int main() {
int i{};
doStuff(i, std::cout);
doStuff(i, std::cout);
doStuff(i, std::cout);
doStuff(i);
doStuff(i);
doStuff(i);
doStuff(i, std::cout);
}
1赞
Some programmer dude
10/4/2022
#4
正如我在评论中提到的,一个可能的解决方案可能是使用简单的函数重载。
// Function for not printing anything
void doStuff(type& thing)
{
thing++;
}
// Function for printing things
void doStuff(type thing, std::ostream& S)
{
// Do the common things first
doStuff(thing);
// And then print
S << "new thing: " << thing << '\n';
}
评论
std::ostream
std::optional<std::reference_wrapper<std::ostream>>