c++ - C++中的平台无关/dev/null

标签 c++ stream ostream default-parameters

Possible Duplicate:
Implementing a no-op std::ostream

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

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

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

最佳答案

编辑:取自@Johannes Schaub - litb 的邮件 here稍作修改:

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 的构造函数它需要一个指向 streambuf 的指针:

Effects: Constructs an object of class basic_ostream, assigning initial values to the base class by calling basic_ios<charT,traits>::init(sb).

来自basic_ios的相关函数, 27.4.4.1 [lib.basic.ios.cons] p3 :

void init(basic_streambuf<charT,traits>* sb);
Postconditions: The postconditions of this function are indicated in Table 89:

表 89 中的重要行:

rdstate() -- goodbit if sb is not a null pointer, otherwise badbit.

如果 badbit设置在 27.6.2.6 [lib.ostream.unformatted] 下描述:

Each unformatted output function begins execution by constructing an object of class sentry. If this object returns true, while converting to a value of type bool, the function endeavors to generate the requested output.

这意味着,如果 sentry是假的,它没有。以下是 sentry 的方法转换为 bool ,取自 27.6.2.3 [lib.ostream::sentry] p3 & p5 :

3) If, after any preparation is completed, os.good() is true, ok_ == true otherwise, ok_ == false.

5) operator bool();
Effects: Returns 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]
  • 表 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

关于c++ - C++中的平台无关/dev/null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6240950/

相关文章:

json - 如何获取 yason :encode-alist to return the encoded string instead of sending it to a stream?

c++ - 为什么将 std::endl 与 ostringstream 一起使用会影响输出速度?

c++ - 处理将 uint8 自动显示为 int 到 ostream

c++ - 未使用代码的开销

c++ - 对于看起来非常好的 C++ 代码,VC++ 中的错误?

c++ - 当 std::wstring 在堆栈上定义时,Hooked NtOpenFile 失败

c++ - c++ : error: must use '.*' or '->*' to call pointer-to-member function in function 中的函数指针

c# - 将大型 xml 文件插入 xml 列的最佳方法(在远程 SQL Server 上)

c++ - 如何自定义ostream C++

c++ - 如果使用 g++,为什么 std::cout 可以转换为 void*?