我一直在编写一个自定义std::streambuf作为日志系统的一部分.但是,我遇到的问题是流的第一段输出没有正确格式化.
这是一个简化的测试用例,不使用任何自定义streambuf或ostream类:
#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无关,而是与评估顺序或与构造函数或其他东西的交互).如果这不是问题,那么是什么?
问题是您不能写入临时流对象.这个:
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*.
底线:不要尝试写入临时流对象.