std :: ostream第一次使用时没有正确格式化const char*

Joh*_*mew 5 c++ iostream

我一直在编写一个自定义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;
}
Run Code Online (Sandbox Code Playgroud)

使用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.
Run Code Online (Sandbox Code Playgroud)

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

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

sbi*_*sbi 8

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

std::ostream(coutbuf) << "blah";
Run Code Online (Sandbox Code Playgroud)

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

std::ostream& operator<<(std::ostream&, ...);
Run Code Online (Sandbox Code Playgroud)

由于rvalues不绑定到非const引用,因此无法调用它们.

我怀疑你的std lib实现<<const char*作为一个自由函数实现的,因此可以回归到某些<<成员std::ostream.在您的实现中,似乎是将任何指针输出为a void*.

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