operator<<(ostream&, T const&)
是支持将类型T
对象输出到流的标准机制,通常还用于通过ostringstream
将自定义类型转换为字符串表示形式(尽管似乎在C ++ 11中也为基本类型提供了to_string
。
对于简单的单数据成员类型,这非常简单:
friend std::ostream& operator<<(std::ostream& str, Simple const& s)
{
return str << s.value;
}
这允许根据流的当前规则输出值 - 即。以所需的数字格式和指定的宽度或填充。
但是,只要您有一个希望输出多个项目的复合类型,就会变得更加复杂:
friend std::ostream& operator<<(std::ostream& str, Complex const& c)
{
return str << s.a << ':' << s.b;
}
乍一看,上面的工作正如预期的那样,这似乎是实现它的最常见方式,至少根据文档。但这是错误的。
有人将Complex视为要显示的单个值并使用setw
为其指定一些理由将会惊讶地发现它们的宽度完全应用于第一个组件而不是“整个值”。并且类作者可能会惊讶于有时他们的值以十六进制打印。
那么,也许我们应该只向原始流输出一个值?
friend std::ostream& operator<<(std::ostream& str, Complex const& c)
{
std::ostringstream s;
s << c.a << ':' << c.b;
return str << s.str();
}
首先,将流转换为字符串然后将其戳回流(并且需要额外的内存分配)感觉有点不对 - 但是使用s.rdbuf()
的另一种选择不起作用因为它被视为多个单独的插入,再次将外部setw
应用于错误的位置。
其次,虽然现在外部setw
按预期处理,但它已与流上的其他设置隔离,例如是否以十六进制显示或要使用的语言环境。也许在某些情况下这是一件好事,但一般来说这似乎不是正确的事情。它还需要单独分配临时缓冲区。
是否有一种优雅的方式来优雅地处理这些事情?