17

我最近被这样一个事实所困扰,ios_base::width和/或必须在每个写入流的项目时重置setw操纵器。

也就是说,您必须这样做:

while(whatever)
{
    mystream << std::setw(2) << myval;
}

而不是这样:

mystream.width(2);
while(whatever)
{
    mystream << myval;
}

好的。

但是有谁知道为什么做出这个设计决定?我是否缺少一些理由,或者这只是标准的一个黑暗角落?

其他流格式修饰符(如链接的 SO 问题中所述)是“粘性的”,而setw不是。

4

2 回答 2

6

哪些操纵器应该只影响下一个操作的决定似乎是基于逻辑和经验观察,即哪些因素倾向于更好地考虑通用功能需求,因此程序员更容易编写和正确。

以下几点让我觉得相关:

  • some_stream << x大部分时间应该都能正常工作
  • 大多数设置宽度的代码会立即或很快地流式传输该值,因此不相关的代码可以假设不会有一些“待定”宽度值影响其输出
  • setfill() 除非有一个 pending 否则不相关setw(),因此不会对some_stream << x我们列表中的声明 产生不利影响
    • 只有当显式设置宽度时,程序员才能/必须考虑填充字符状态是否也合适,基于他们对更大调用上下文的了解
  • 一组值使用相同的填充字符是很常见的
  • 其他操纵器喜欢hex并且oct是持久的,但它们的使用通常是在一个代码块中,该代码块要么弹出先前的状态,要么(讨厌但更容易)将其设置回十进制

从这一点开始回答你的问题......

  • 如果setw()是持久的,则需要在每个流语句之间重置它以防止不必要的填充...
于 2011-05-06T01:34:20.910 回答
4

我看到它的方式是:如果你希望它被统一应用,你总是可以做如下的事情。

int width =2;
while(whatever)
{
    mystream << std::setw(width) << myval;
}

但如果它像你提到的那样粘稠:

mystream.width(2);
while(whatever)
{
    mystream << myval;
}

如果我想要每行都有不同的宽度,我必须继续设置宽度。

所以基本上这两种方法几乎相同,我喜欢或不喜欢它们取决于我现在在做什么。

于 2011-05-06T00:20:51.917 回答