我最近在创建 stringstream
时遇到问题,因为我错误地假设 std::setw()
会影响每次插入的字符串流,直到我明确更改它。但是,插入后它始终未设置。
// With timestruct with value of 'Oct 7 9:04 AM'
std::stringstream ss;
ss.fill('0'); ss.setf(ios::right, ios::adjustfield);
ss << setw(2) << timestruct.tm_mday;
ss << timestruct.tm_hour;
ss << timestruct.tm_min;
std::string filingTime = ss.str(); // BAD: '0794'
所以,我有几个问题:
- 为什么
setw()
是这样的? - 其他机械手也这样吗?
std::ios_base::width()
和std::setw()
之间的行为是否存在差异?- 最后是否有明确记录这种行为的在线参考资料?我的供应商文档(MS Visual Studio 2005)似乎没有清楚地表明这一点。
原文由 John K 发布,翻译遵循 CC BY-SA 4.0 许可协议
以下评论的重要说明:
马丁:
查尔斯:
以下是导致上述结论的讨论:
查看代码,以下操纵器返回对象而不是流:
这是一种将操作仅应用于应用于流的下一个对象的常用技术。不幸的是,这并不排除它们具有粘性。测试表明,除了
setw
之外,所有这些都是粘性的。所有其他操纵器都返回一个流对象。因此,它们更改的任何状态信息都必须记录在流对象中,因此是永久性的(直到另一个操纵器更改状态)。因此,以下操纵器必须是 粘性 操纵器。
这些操纵器实际上对流本身而不是流对象执行操作(尽管从技术上讲,流是流对象状态的一部分)。但我不相信它们会影响流对象状态的任何其他部分。
结论是 setw 似乎是我的版本中唯一不粘的操纵器。
对于查尔斯来说,一个简单的技巧只影响链中的下一个项目:
这是一个示例,如何使用对象临时更改状态,然后通过使用对象将其放回原处: