首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ostream函数中使用stringstream

在ostream函数中使用stringstream
EN

Stack Overflow用户
提问于 2012-10-16 05:16:51
回答 3查看 593关注 0票数 8

我正在考虑为一些数学类(矩阵、向量等)提供ostream运算符。一位朋友已经注意到,用于std::complexostream运算符的gcc标准库实现包括内部使用字符串流来格式化输出,然后再将其传递给实际的ostream

代码语言:javascript
复制
///  Insertion operator for complex values.
template<typename _Tp, typename _CharT, class _Traits>
  basic_ostream<_CharT, _Traits>&
  operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
{
  basic_ostringstream<_CharT, _Traits> __s;
  __s.flags(__os.flags());
  __s.imbue(__os.getloc());
  __s.precision(__os.precision());
  __s << '(' << __x.real() << ',' << __x.imag() << ')';
  return __os << __s.str();
}

这种模式在boost中也很明显。我们正在尝试确定这是否是一个值得遵循的模式。有人担心,它涉及到包含字符串流的额外标头,并且在字符串流中需要额外的堆分配,这可能是可以避免的。

最合理的建议是,如果客户端需要该功能,那么他们可以创建字符串流并自行执行预传递。

谁能帮助我理解为什么这会被认为是好的实践,以及我是否应该采用它?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-16 05:23:14

考虑一下,如果在ostream上设置输出宽度,然后向其写入std::complex -您不希望宽度只影响第一个输出操作(即'('字符)

代码语言:javascript
复制
std::complex i(0, 1);
std::cout << std::setw(10) << std::left << i;

这应该打印"(0,1)     "而不是"(         0,1)"

通过将整个输出形成为单个字符串,然后将其写出,输出将遵循流上设置的字段宽度和其他格式化标志。

票数 6
EN

Stack Overflow用户

发布于 2012-10-16 05:26:43

在另一个响应中引用的线程化原因不会真正起作用:字符串仍然可以在流缓冲级分割,因为这些操作在从多个线程调用时不是原子的。

但是,有两个相关的考虑因素:

  1. 对于您要临时更改格式标志设置的某些输出。例如,您希望确保某些字符串使用十六进制表示法显示,对于其他十进制表示法,您希望将流恢复到其原始状态。
  2. 更重要的是,输出的width()的含义是整个格式化字符串至少应该占用的字符数。如果在内部对另一个输出运算符使用输出运算符,则应该使第一个元素占据宽度,而不是生成由多个组件组成的整个字符串。例如,对于复数,实数元素将占用width(),而不是实数元素、逗号和虚数元素的组合。
票数 4
EN

Stack Overflow用户

发布于 2012-10-16 05:22:10

此模式的一个主要目的是避免保留原始流的操纵器/标志,并在返回之前重新设置它们。Boost.IoStateSavers消除了这方面的需求,所以我想说使用这个库将是一个更好的实践。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12904155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档