检查 ostream 对象是否为 cout 或 ofstream,c++

11

在C++中,有没有一种方法可以检查ostream对象是cout还是ofstream对象?

例如:

ostream& output(ostream& out)
{
    if (out == cout)
        return out;
    else
    {
        out << "因为不是去控制台所以不同" << endl;
        return out;
    }
}

我想这样做的原因是,我想重载<<运算符,根据使用的流类型执行两个不同的操作。

是否可能每次将<<运算符重载两次,分别用于不同类型的流?

更新以更好地反映意图。


请提供一个std::ostream,可以从std::cout或std::ofstream文件中获取。相关:https://dev59.com/8HRC5IYBdhLWcg3wP-Zh#366969 - user195488
1
你做这件事的动机是什么?在我看来,这似乎是一个非常糟糕的想法。 - Brian
@Brian:我在上面添加了,我想使用<<运算符根据流执行两种不同的操作,欢迎提出其他方法。 - Jordan
@Jordan:是的,我知道你想要使用<<根据流执行两种不同的操作。为什么你想这样做呢?在我看来,这似乎是一个非常糟糕的想法。 - Brian
1
使用流的整个目的是使目标匿名,因此无论使用什么类型的流,一切都看起来相同。如果有人将文件流连接到文件描述符2(大多数系统上的标准输出),会发生什么情况?这将是完全不同的流,但对于操作系统来说,它将进入控制台。或者,如果操作系统将std :: cout连接到文件,那么这就远离应用程序空间,以至于在应用程序内部无法检测到。 - Martin York
听起来你真正想问的问题可能是“我如何检测输出是否到终端”? - Cascabel
4个回答

15

所以,我轻松地称之为“别名”流缓冲区。我想那不是太清楚,所以我编辑了我的评论以使其更清晰。 - sehe

6
似乎您真正想知道的不是流是否为cout,而是底层文件描述符是否连接到终端?如果是这样,您需要底层文件描述符。不幸的是,您无法从iostream获取它。如果可以使用cstdio而不是iostream,则可以。如果您确实拥有文件描述符,则确定是否正在写入终端只需查看tcgetattr()是否返回-1即可。
此外,请不要让任何人告诉您不要实现您需要的某些功能,因为它会破坏某些不完美的抽象概念。如果您确实需要不同的行为,请尽管采取必要措施以实现该功能。

4

可以通过检查流的“identity”来实现:if ( &out == &cout ) ...

然而,我对这个测试的有用性持怀疑态度。如果您的函数可以处理任何输出流,为什么要关心它使用的流呢?


14
为什么?可能是为了将一件事情写入文件,同时将另一件事情输出到终端。例如,在向终端写入内容时使用转义序列来着色输出。但是,如果 STDOUT 被重定向,这种做法就不会起作用。 - atzz
这种方法不太可靠。在获取地址之前,您应该将对象强制转换为相同的类型(在这种情况下是某种公共基本流类型)。 - Martin York
@Martin York:对于单继承树也是这样吗? - xtofl
@sehe:我不知道。在那种情况下,你能做什么? - xtofl
@sehe:顺便问一下,什么是别名流缓冲区?(参见https://dev59.com/rFXTa4cB1Zd3GeqPzDDn) - xtofl
我指的是rdbuf()共享/别名:请参见我的早期答案https://dev59.com/yHA75IYBdhLWcg3wZ4Fr#5293107 - sehe

1

我认为根据你要流式传输的对象来改变流式传输方式是一个可怕的想法,完全忽略了流对象预期工作的整个重点。因此,我会创建一个成员类或函数,返回一个处理流式传输方式不同类型的对象。例如,如果您想提供一个带颜色的流,您可以调用:

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

编辑:

你关于处理流的建议是个坏主意,因为你不知道其他人会如何使用你的代码。根据对象进行流传输的行为完全不直观。这就像有一个函数,返回值取决于谁调用它而不是取决于其参数一样,尽管我承认流技术上是一个参数。

至于如何以这种方式实现,一种方法是创建一个colorstreamer,使这个新类成为myclass的成员,并使myclass成为colorstreamer的成员,然后将colorstreamer的流操作符设为myclass的友元。我更担心调用函数的语义(即使用.colorstreamer来控制它的流输出方式,而不是使用流本身),而不是如何实现它。我提出的实现方法很可能是一种不好的做法;我的C++已经生疏了。


你可以再详细解释一下为什么这是一个不好的主意吗?并且你能更具体地说明一下你如何处理这个问题吗? - Jordan
@Jordan:已编辑以回答您的问题,尽管我认为Martin York在您的问题上的评论(即“使用流的整个重点是...”)更好地解释了为什么这是一个不好的想法。 - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接