std::ostringstream作为函数参数出现问题

4

今天我在一个简单的打印函数上遇到了问题,但我真的不知道该如何解决这个问题。基本上,我想把我的字符串传递给一个函数,并以std::cout的方式打印出来,就像这样:

foo(std::ostringstream() << "Hello" << " World!");

根据我所读到的信息,应该可以通过类似以下函数的方式实现:
void foo(std::ostringstream& in)

但是在实现时,我得到了一些奇怪的行为:
#include <iostream>
#include <sstream>

void foo(std::ostringstream& in)
{
    std::cout << in.str();
}

int main()
{
    std::ostringstream working;
    working << "Hello" << " World!";
    foo(working);                   // OK
    std::ostringstream notWorking;
    notWorking << "Hello";
    foo(notWorking<<" World!");     // Not OK?!
    return 0;
}

虽然第一次调用foo函数看起来很好,像预期的那样工作,但第二次却拒绝编译,尽管它们(从我的角度来看)在技术上应该是相同的。

错误信息:

error C2664: 'void foo(std::ostringstream &)': cannot convert parameter 1 from 'std::basic_ostream<char,std::char_traits<char>>' to 'std::ostringstream &'

我正在使用Win7 x64上的MS Visual Studio 2013 Express。

3个回答

4

IO操作的移位运算符重载使用基本流进行引用。也就是说:

std::ostream& operator<<( std::ostream& os , foo myfo )
{
    os << myfoo;

    return os;
}

因此,在函数参数中使用std :: ostream而不是std :: ostringstream

void f( std::ostream& stream );

谢谢,看起来它正在工作。但是我如何从std::ostream返回到std::string呢?例如将其移入std::cout似乎不起作用。 - CyDek
2
@CyDek 如果 foo 真的需要一个 ostringstream,你应该使用你的可行方法,而不是修改函数以接受一个 ostream。如果你真的想要遵循你的其他方法,那么你可以将 ostream 强制转换回 ostringstream (static_cast<std::ostringstream&>(in).str()),但是如果有人使用其他类型的 ostream 调用 foo,那么它就是未定义的行为。 - Praetorian
@Praetorian 谢谢,非常好用。由于我只是为了学习而进行实验,所以我对此非常满意 :) - CyDek

2
这是因为第二个表达式
notWorking<<" World!"

返回一个 std::ostream& 而不是一个 std::ostringstream&


0
你出现错误的原因是尝试将一个ostream隐式向下转换为ostringstream,因为<<运算符的结果始终是ostream&,无论具体的字符串类型如何。将foo()更改为接受ostream&应该可以解决这个问题,除非您需要在foo的实现中特别依赖于ostringstream功能,在这种情况下,您可以使用dynamic_cast
此外,在您的foo(std::ostringstream() << "Hello" << " World!");示例中构造临时ostringstream会得到一个rvalue。 foo()需要对流的lvalue引用。您可能可以通过将foo()更改为接受rvalue引用:std::ostream&&来解决这个问题。

什么是临时的 ostringstream - Praetorian
@Praetorian: foo(std::ostringstream() << "Hello" << " World!"); 尽管 ostream/ostringstream 的区别也很重要。 - Jon Purdy
哦,抱歉,我错过了第一行。不管怎样,他的代码示例中没有这样的东西。 - Praetorian

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