5

我一直在编写一个自定义std::streambuf作为日志系统的一部分。但是,我遇到了来自流的第一段输出格式不正确的问题。

这是一个不使用任何自定义streambufostream类的简化测试用例:

#include <iostream>

int main()
{
    std::streambuf *coutbuf = std::cout.rdbuf();
    std::ostream(coutbuf) << "test" << ": writing to cout using a separate ostream." << std::endl;
    return 0;
}

使用 g++ 编译:

$ g++ --version
g++ (Ubuntu 4.4.1-4ubuntu8) 4.4.1

$ g++ -o fail reduced-case.cpp

$ ./fail
0x400c80: writing to cout using a separate ostream.

请注意,第一个字符串文字(“test”)被格式化为通用指针(字符串的地址以十六进制输出),而第二个字符串文字的格式正确。

我唯一能想到的是,直接使用这样的新构造std::ostream(即,不将其放入变量)是无效的。如果是这种情况,我非常想知道究竟是什么使它无效(我认为这与 iostreams 无关,而是与评估顺序或与构造函数或其他东西的交互)。如果这不是问题,那是什么?

4

2 回答 2

8

问题是您不能写入临时流对象。这:

std::ostream(coutbuf) << "blah";

没有按预期工作,因为左侧参数 foroperator<<()是一个右值。但是,作为自由函数重载的所有运算符都将流的非常量引用作为其左侧参数:

std::ostream& operator<<(std::ostream&, ...);

由于右值不绑定到非常量引用,它们不能被调用。

我怀疑你的 std lib 实现<<是作为一个自由函数实现的const char*,因此不得不回退到. 在您的实现中似乎是将任何指针输出为.<<std::ostreamvoid*

底线:不要尝试写入临时流对象。

于 2009-11-19T17:13:35.347 回答
1

您不能像这样使用临时流对象。为临时变量命名。

#include <iostream>

int main()
{
    std::streambuf *coutbuf = std::cout.rdbuf();
    std::ostream os(coutbuf);
    os << "test" << ": writing to cout using a separate ostream." << std::endl;
    return 0;
}
于 2009-11-19T17:15:42.940 回答