本文介绍了C++ 中的平台独立/dev/null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能的重复:
实现无操作 std::ostream

在 C++ 中是否有任何与 NULL 等效的流?如果用户想要将内部输出到某个地方,我想编写一个接收流的函数,但如果不是,则输出会进入某个假位置

Is there any stream equivalent of NULL in c++? I want to write a function that takes in a stream if the user wants to have the internal outputted to somewhere, but if not, the output goes into some fake place

void data(std::stream & stream = fake_stream){
    stream << "DATA" ;
}

我希望能够选择做 data()data(std::cout)

i want to be able to chose to do data() or data(std::cout)

推荐答案

编辑:摘自@Johannes Schaub - litb 的邮件 这里 稍作修改:

Edit: Taken from @Johannes Schaub - litb's mail here with slight modifications:

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 并默默忽略任何写入:


Now, this looks cool and all, but the following is way shorter and works, because if a null pointer is provided to the constructor of ostream, it automatically sets the badbit and silently ignores any writes:

// 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 的构造函数,它接受一个指向 streambuf:

The standard guarantees this works, beginning from 27.6.2.2 [lib.ostream.cons] p1 which describes the constructor of ostream that takes a pointer to 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* sb);
后置条件:该函数的后置条件如表89所示:

表 89 中的重要行:

The important row from Table 89:

rdstate() -- 如果 sb 不是空指针则为 goodbit,否则为 badbit.

27.6.2.6 [lib.ostream.unformatted] 中描述了如果设置了 badbit 会发生什么:

What happens if the badbit is set is described under 27.6.2.6 [lib.ostream.unformatted]:

每个未格式化的输出函数通过构造一个sentry 类的对象开始执行.如果此对象返回 true,则在转换为 bool 类型的值时,该函数会努力生成请求的输出.

这意味着,如果 sentry 为假,则不会.下面是 sentry 如何转换为 bool,取自 27.6.2.3 [lib.ostream::sentry] p3 &p5:

This implies that, in case the sentry is false, it does not. Here is how the sentry converts to bool, taken from 27.6.2.3 [lib.ostream::sentry] p3 & p5:

3) 如果在任何准备工作完成后,os.good()trueok_ == true 否则,ok_ == false.

5) operator bool();
效果:返回ok_.

5) operator bool();
Effects: Returns ok_.

(ok_bool 类型的 ostream::sentry 的成员.)

(ok_ is a member of ostream::sentry of type bool.)

请注意,这些引号仍然存在于 C++11 中,只是在不同的地方.按照在此答案中出现的顺序:

Note that these quotes are still present in C++11, just in different places. In order of appearance in this answer:

  • 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]
  • 表 89 => 表 128
  • 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
  • 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]
  • Table 89 => Table 128
  • 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

这篇关于C++ 中的平台独立/dev/null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 06:58
查看更多