字符串流的奇怪行为通过引用传递

时间:2012-03-11 20:42:04

标签: c++ stringstream

对于一个项目,我想使用stringstream来传输数据。为了实现这个目标,我必须将一些stringstream作为参数传递给某个函数,但是当我输出stringstreams时,我会看到类似地址的东西。

代码:

#include <iostream>
#include <sstream>

void doStuff(const std::iostream& msg)
{
    std::cerr << msg << std::endl;
}

int main(void)
{
    doStuff(std::stringstream("av"));
}

输出是: 0xbff4eb40

有人可以解释为什么我在传递右值时会得到一个地址吗?

为什么我不能按值传递字符串流?

2 个答案:

答案 0 :(得分:4)

您可能想要访问stringstream存储其数据的字符串:

void doStuff(const std::stringstream& msg)
{
    std::cerr << msg.str() << std::endl;
}

代码中发生的事情是iostreams包含void* operator,如果流包含任何错误或已达到EOF,则返回0,否则返回另一个值。这对于错误检查很有用。

当您尝试将流写入std::cerr时,编译器会意识到可以使用该运算符将流转换为void *,并且可以将void *写入ostream(运算符&lt;&lt; ;已定义),因此使用它。

请注意,我更改了方法的签名,以便它接收std :: stringstream作为参数,因为未定义std :: iostream :: str(此方法仅适用于字符串流)。

答案 1 :(得分:1)

你得到一个地址,因为它(和其他流一样)转换为void *(主要用作布尔值,看看读/写流是否失败)。

您不能按值传递它,因为流(通常,不仅仅是字符串流)不支持复制和/或分配。

要打印流的内容,您可以执行以下操作:

void dostuff(std::iostream &msg) { 
    std::cerr << msg.rdbuf() << "\n";
}

编辑:这是一个完整的演示程序:

#include <iostream>
#include <sstream>

void show(std::ostream &os) { 
    std::cout << os.rdbuf() << "\n";
}


int main(){ 
    std::stringstream test("whatever");
    show(test);
    return 0;
}

当我执行它时,我得到的输出是预期的“无论什么”。