可能重复:
实现一个无操作的std::ostream
C++中有没有流的等效NULL?我想编写一个函数,如果用户想将内部输出到某个地方,则接受流作为参数,但如果不需要,则输出到某个虚假的位置。
void data(std::stream & stream = fake_stream){
stream << "DATA" ;
}
我希望能够选择执行data()
或data(std::cout)
。
可能重复:
实现一个无操作的std::ostream
C++中有没有流的等效NULL?我想编写一个函数,如果用户想将内部输出到某个地方,则接受流作为参数,但如果不需要,则输出到某个虚假的位置。
void data(std::stream & stream = fake_stream){
stream << "DATA" ;
}
我希望能够选择执行data()
或data(std::cout)
。
编辑:取自 @Johannes Schaub - litb 的邮件 这里,稍作修改:
template<typename Ch, typename Traits = std::char_traits<Ch> >
struct basic_nullbuf : std::basic_streambuf<Ch, Traits> {
typedef std::basic_streambuf<Ch, Traits> base_type;
typedef typename base_type::int_type int_type;
typedef typename base_type::traits_type traits_type;
virtual int_type overflow(int_type c) {
return traits_type::not_eof(c);
}
};
// convenient typedefs
typedef basic_nullbuf<char> nullbuf;
typedef basic_nullbuf<wchar_t> wnullbuf;
// buffers and streams
// in some .h
extern std::ostream cnull;
extern std::wostream wcnull;
// in a concrete .cpp
nullbuf null_obj;
wnullbuf wnull_obj;
std::ostream cnull(&null_obj);
std::wostream wcnull(&wnull_obj);
使用这些:
void data(std::ostream& stream = cnull){
// whatever...
}
现在,这看起来很酷,但接下来的方法更加简短且奏效,因为如果向 ostream
的构造函数提供空指针,它会自动设置 badbit 并静默地忽略任何写入:// in .h
extern std::ostream cnull;
extern std::wostream wcnull;
// in .cpp
std::ostream cnull(0);
std::wostream wcnull(0);
标准保证这个工作,从27.6.2.2 [lib.ostream.cons] p1
开始描述了带有指向streambuf
的指针的ostream
构造函数的内容:
来自效果:构造一个
basic_ostream
类的对象,通过调用basic_ios<charT,traits>::init(sb)
为基类分配初始值。
basic_ios
的相关函数27.4.4.1 [lib.basic.ios.cons] p3
:
表89中的重要行:
void init(basic_streambuf<charT,traits>* sb);
后置条件:此函数的后置条件在表89中指示:
如果设置了rdstate() -- 如果sb不是空指针,则为goodbit,否则为badbit。
badbit
,则在27.6.2.6 [lib.ostream.unformatted]
下描述了会发生什么:
这意味着,如果每个未格式化的输出函数都以构造一个
sentry
类对象开始执行。如果该对象在转换为bool
类型时返回true,则努力生成所请求的输出。
sentry
为false,则不会生成输出。以下是sentry
如何转换为bool
,取自27.6.2.3 [lib.ostream::sentry] p3 & p5
:
(3) 如果完成任何准备工作后,
os.good()
为true
,则ok_ == true
,否则ok_ == false
。5)
operator bool();
效果:返回ok_。
ok_
是ostream::sentry
的一个类型为bool
的成员。)
27.6.2.2 [lib.ostream.cons] p1
=> 27.7.3.2 [ostream.cons] p1
27.4.4.1 [lib.basic.ios.cons] p3
=> 27.5.5.2 [basic.ios.cons]
27.6.2.6 [lib.ostream.unformatted]
=> 27.7.3.7 [ostream.unformatted] p1
27.6.2.3 [lib.ostream::sentry] p3 & p5
=> 27.7.3.4 [ostream::sentry] p4 & p5
os.good()
有区别吗?使用std::ostream os(nullptr)
,assert(os)
将会失败,而使用std::ostream os(&nullobj)
,assert(os)
则不会?我只是猜测。 - HuguesLinux文件/dev/null就像你正在寻找的黑洞一样。在Windows中有一个叫做NUL:的设备。我从未尝试打开过那个文件,但我曾经在命令行中使用过它。
<<
重载中接受参数,然后简单地不对它们进行任何操作即可。 - Chris Eberlestd::ostream stream = NUL
和 std::ostream stream = std::ostream(NUL)
不适用于参数。请问我该如何使用它? - calccryptostd::ostream stream("/dev/null")
。 - Xeo你可以尝试使用ostream(NULL,false),第一个输入是目标输出,我不知道第二个输入确切的含义,但在跟踪代码后,似乎只是因为ostream没有写入的位置,调用operator <<
被ostream忽略了。我的意思是,在第一次调用中,状态会变为bad,之后由于流的状态,始终会忽略输入数据,因此你可以使用以下代码:
void data(std::ostream & stream = ostream(NULL,false)){
stream << "DATA" ;
}
const T&
引用,但无法将常量流写入。我认为MSVC允许这种方式作为扩展,但是... - Xeo