c++ 中的平台独立 /dev/null

发布于 2024-11-14 10:30:39 字数 452 浏览 4 评论 0原文

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

在 c++ 中是否有与 NULL 等效的流?我想编写一个函数,如果用户希望将内部输出到某个地方,则该函数会接收流,但如果没有,输出会进入一些虚假的地方,

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

我希望能够选择执行 data()< /code> 或 data(std::cout)

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

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" ;
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神魇的王 2024-11-21 10:30:39

编辑:摘自 @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,它接受一个指向streambuf的指针:

作用:构造basic_ostream类的对象,通过调用basic_ios::init(sb)为基类分配初始值。 p>

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

void init(basic_streambuf* sb);
后置条件:该函数的后置条件如表 89 所示:

表 89 中的重要行:

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

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

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

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

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

5) 运算符 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]
  • 表 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

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);

Use those:

void data(std::ostream& stream = cnull){
  // whatever...
}

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);

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:

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

The relevant function from 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:

The important row from Table 89:

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

What happens if the badbit is set is described under 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.

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) If, after any preparation is completed, os.good() is true, ok_ == true otherwise, ok_ == false.

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

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


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]
  • 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
深居我梦 2024-11-21 10:30:39

Linux 文件 /dev/null 是一个像你正在寻找的黑洞。在 Windows 中,有一个名为 NUL: 的设备。我从未尝试过打开该文件,但我从命令行使用过它

Linux file /dev/null is a black hole like you're looking for. In Windows there's a device called NUL:. I've never tried to open that file, but I've used it from the command line

摇划花蜜的午后 2024-11-21 10:30:39

你可以尝试 ostream(NULL,false),第一个输入是目标输出,我不知道第二个输入的确切含义,但在跟踪代码后,似乎只是因为 ostream 没有地方可写,调用 operator < ;< 被 ostream 忽略。我的意思是,在第一次调用状态更改为坏,之后它总是忽略输入数据,因为流状态,所以你可以使用以下代码:

void data(std::ostream & stream = ostream(NULL,false)){
    stream << "DATA" ;
}

you can try ostream(NULL,false), the first input is target output and I don't know what the second input exaclty mean but after tracing code it seems just because ostream has no place to write to, calling operator << is just ignored by ostream. I mean in the first call state changes to bad and after that it's always ignoring input data because of stream state ,so you can use the following code :

void data(std::ostream & stream = ostream(NULL,false)){
    stream << "DATA" ;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文