从空缓冲区构造`std :: ostream`是否有效?

Lig*_*ica 20 c++ iostream std c++11

考虑以下:

std::ostream out(nullptr);
Run Code Online (Sandbox Code Playgroud)

这是合法的,定义明确吗?


如果我现在这样做:

out << "hello world\n";
Run Code Online (Sandbox Code Playgroud)

这是合法的,定义明确吗?如果是这样的话,大概这是一种无操作?

Lig*_*ica 24

是的,实例化该流是合法且定义良好的.您可以安全地将其与另一个流交换,或者稍后给它一个新的指针(这次是对现有的缓冲区).输出操作本身确实是一个无操作.

原因如下:

  1. 构造没有非null前置条件,并且只有这个后置条件:

    [C++11: 27.7.3.2/2]:后置条件:rdbuf() == sb.

  2. 有趣的是,它明确指出sb在构造函数中不应该执行任何操作:

    [C++11: 27.7.3.2/4]:备注:不执行任何操作rdbuf().

  3. 但请注意:

    [C++11: 27.7.3.2/1]:效果:构造类的对象,basic_ostream通过调用basic_ios<charT,traits>::init(sb)(27.5.5.2)将初始值赋给基类.

  4. init(sb)调用NULL badbit时,该调用具有设置流的效果sb:

    [C++11: 27.5.5.2/3]: 后置条件:此函数的后置条件如表128所示.

    [C++11: Table 128]: [..] rdstate():goodbitif sb不是空指针,否则 badbit.[..]

  5. 输出操作导致相当于取消引用空指针的操作:

    [C++11: 27.7.3.1/2]:两组成员函数签名共享公共属性:格式化输出函数(或插入器)和未格式化的输出函数.两组输出函数都通过等同于调用的操作生成(或插入)输出字符rdbuf()->sputc(int_type).他们可以使用的其他公共成员basic_ostream除了他们不得以任何虚拟成员rdbuf()除外overflow(),xsputn()sync().

    除了它从来没有这么远,因为basic_ostream::sentry建设:

    [C++11: 27.7.3.4/3]:如果任何准备完成后,os.good()就是true,ok_ == true否则ok_ == false.

    并且,对于explicit operator basic_ostream::sentry::bool() const;:

    [C++11: 27.7.3.4/5]:效果:退货ok_.

    和:

    [C++11: 27.7.3.7/1]:每个未格式化的输出函数通过构造类的对象开始执行sentry.如果此对象返回true,则在转换为type的值时bool,该函数会尝试生成请求的输出.[..]

    ......意味着在badbit已经设定的情况下根本不会发生输出操作.

在C++ 03中也是如此.