可能重复:
实现无操作 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
描述的构造函数开始,ostream
它需要一个指向 a 的指针streambuf
:
效果:构造一个类的对象,
basic_ostream
通过调用为基类分配初始值basic_ios<charT,traits>::init(sb)
。
的相关函数basic_ios
, 27.4.4.1 [lib.basic.ios.cons] p3
:
void init(basic_streambuf<charT,traits>* sb);
后置条件:该函数的后置条件如表 89 所示:
表 89 中的重要行:
rdstate() -- 如果 sb 不是空指针,则为goodbit,否则为badbit。
如果badbit
设置了会发生什么如下所述27.6.2.6 [lib.ostream.unformatted]
:
每个未格式化的输出函数通过构造 class 的对象开始执行
sentry
。如果此对象返回 true,则在转换为 bool 类型的值时,该函数会努力生成请求的输出。
这意味着,如果sentry
是假的,它不会。以下是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
。)
请注意,这些引号仍然存在于 C++11 中,只是出现在不同的地方。在这个答案中出现的顺序:
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
Linux 文件 /dev/null 是您正在寻找的黑洞。在 Windows 中有一个名为 NUL: 的设备。我从未尝试打开该文件,但我已从命令行使用它
你可以试试 ostream(NULL,false),第一个输入是目标输出,我不知道第二个输入是什么意思,但是在跟踪代码之后,似乎只是因为 ostream 没有地方可以写入,operator <<
ostream 只是忽略了调用. 我的意思是在第一次调用状态更改为坏之后,由于流状态,它总是忽略输入数据,因此您可以使用以下代码:
void data(std::ostream & stream = ostream(NULL,false)){
stream << "DATA" ;
}