【问题标题】:Check if ostream object is cout or ofstream, c++检查 ostream 对象是 cout 还是 ofstream,c++
【发布时间】:2011-03-20 02:57:29
【问题描述】:

在 C++ 中有没有办法检查 ostream 对象是 cout 还是 ofstream 对象?

类似:

ostream& output(ostream& out)
{
    if (out == cout)
        return out;
    else
    {
        out << "something different because its not going to the console" << endl;
        return out;
    }
}

我想这样做的原因是,我想重载 &lt;&lt; 运算符,根据它使用的流类型来做两件不同的事情。

是否可以每次使用不同类型的流重载 &lt;&lt; 运算符两次?

更新以更好地反映意图。

【问题讨论】:

  • 您这样做的动机是什么?对我来说,这似乎是一个非常糟糕的主意。
  • @Brian:我在上面添加了,我想使用 &lt;&lt; 运算符根据流做两件不同的事情,欢迎使用替代方法
  • @Jordan:是的,我知道你想使用&lt;&lt; 来根据流做两件不同的事情。你为什么要这样做?对我来说,这似乎是一个非常糟糕的主意。
  • 使用流的全部意义在于使其对目的地匿名,因此无论您使用什么类型的流,一切看起来都一样。如果有人将文件流连接到文件描述符 2(大多数系统上的标准输出)会发生什么。这将是一个完全不同的流,但对于操作系统来说,它将进入控制台。或者,如果操作系统将 std::cout 连接到文件怎么办,这超出了应用程序空间,以至于在应用程序内部无法检测到。

标签: c++ cout ofstream ostream


【解决方案1】:

通过检查流缓冲区身份,您肯定会走得更远

if (s.rdbuf() == std::cout.rdbuf())

这是因为将流交叉分配/别名流到缓冲区非常简单,请参阅http://www.cplusplus.com/reference/iostream/ios/rdbuf/ 和 Josuttis 书

【讨论】:

  • 这就是我轻描淡写地称为“混叠”流缓冲区的方法。我想这不是太清楚,所以我编辑了我的 cmets 以使其更清晰。
【解决方案2】:

听起来您真正想知道的不是流是否为 cout,而是底层文件描述符是否附加到终端?如果是这样,您需要底层文件描述符。不幸的是,你不能从 iostream 中得到它。如果可以使用 cstdio 而不是 iostream,那么您可以。如果您确实有文件描述符,那么确定您是否正在写入终端很简单,就像查看 tcgetattr() 是否返回 -1。

另外,不要让任何人告诉你不要实现一些你需要的功能,因为它会损害一些泄漏抽象的纯度。如果你真的需要不同的行为,那么就做你需要做的事情来产生那个功能。

【讨论】:

    【解决方案3】:

    可以通过检查流的“身份”:if ( &amp;out == &amp;cout ) ...

    但是,我怀疑此测试的实用性。如果你的函数可以处理任何输出流,为什么还要关心它使用的是什么流呢?

    【讨论】:

    • 为什么?也许,将一件事写入文件,将另一件事写入终端。例如,在写入终端时使用转义序列为输出着色。虽然如果 STDOUT 被重定向,它将不起作用。
    • 这不可能一直有效。在获取它们的地址之前,您应该将对象转换为相同的类型(在这种情况下,某种形式的常见基本流类型)。
    • @Martin York:单继承树也是这样吗?
    • @sehe:我不知道。在这种情况下你能做什么?
    • @sehe:顺便说一句,什么是别名流缓冲区? (cfr stackoverflow.com/questions/5296484/…)
    【解决方案4】:

    我认为根据要流式传输的对象更改流式传输方式是一个可怕的想法,它完全忽略了流对象的工作原理。因此,我将创建一个成员类或函数,它返回一个以不同方式处理流的类型的对象。因此,例如,如果您想提供彩色流,您可以调用:

    std::cout << myclass.colorstreamer << endl;
    

    编辑:

    您处理流的建议是个坏主意,因为您不知道其他人将如何使用您的代码。根据正在执行流式传输的对象,流的行为不同是完全不直观的。我把它比作一个函数,它根据谁调用它而不是取决于它的参数是什么返回不同的结果,尽管我承认从技术上讲流是一个参数。

    至于如何做到这一点,一种方法是创建一个colorstreamer,使这个新类成为myclass的成员,并使myclass成为colorstreamer的成员,然后使colorstreamer的流操作员是myclass 的朋友。我更担心调用函数的语义(即使用.colorstreamer 来控制它的流式传输方式而不是使用流本身),而不是如何实现它。我对如何实现它的建议很可能是一个不好的方法;我的 C++ 生锈了。

    【讨论】:

    • 您能否详细说明一下为什么这是一个坏主意,您能否更具体地说明如何以您的方式解决问题?
    • @Jordan:已编辑以回答您的问题,尽管我认为 Martin York 对您的问题的评论(即“使用流的全部意义......”)对于为什么它不好想法。
    猜你喜欢
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2015-12-10
    相关资源
    最近更新 更多