哪个自吹自擂的操纵者是“粘性”的?

哪个自吹自擂的操纵者是“粘性”的?

最近我在创建一个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()?

  • 最后,是否有一个在线参考可以清楚地记录这种行为?我的供应商文档(MSVisualStudio 2005)似乎没有清楚地显示这一点。



翻阅古今
浏览 324回答 3
3回答

GCT1015

以下评论的重要说明:马丁:@Chareles:那么根据这个要求,所有的机械手都是粘性的。除了SET,它似乎在使用后被重置。查尔斯:一点儿没错!而setw似乎行为不同的唯一原因是,格式化的输出操作需要显式地.Width(0)输出流。以下是导致上述结论的讨论:查看代码,以下操作程序返回一个对象,而不是流:setiosflags resetiosflags setbase setfill setprecision setw这是一种将操作应用于仅应用于流的下一个对象的常见技术。不幸的是,这并不能阻止他们粘在一起。测试表明,除了setw粘粘的。setiosflags:&nbsp;&nbsp;Stickyresetiosflags:Stickysetbase:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stickysetfill:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stickysetprecision:&nbsp;Sticky所有其他操作器都返回流对象。因此,它们更改的任何状态信息都必须记录在流对象中,因此是永久的(直到另一个机械手改变状态)。因此,下列机械手必须是粘操纵者。[no]boolalpha[no]showbase[no]showpoint[no]showpos[no]skipws[no]unitbuf[no]uppercase dec/&nbsp;hex/&nbsp;oct fixed/&nbsp;scientific internal/&nbsp;left/&nbsp;right这些操纵器实际上对流本身执行操作,而不是对流对象执行操作(尽管从技术上讲,流是流对象状态的一部分)。但我不认为它们会影响流对象状态的任何其他部分。ws/&nbsp;endl/&nbsp;ends/&nbsp;flush结论是,在我的版本中,setw似乎是唯一不粘的操纵者。对查尔斯来说,一个简单的技巧就是只影响链中的下一个项目:下面是一个示例,说明如何使用对象临时更改状态,然后通过使用对象将其放回原处:#include <iostream>#include <iomanip>// Private object constructed by the format object PutSquareBracketstruct SquareBracktAroundNextItem{&nbsp; &nbsp; SquareBracktAroundNextItem(std::ostream& str)&nbsp; &nbsp; &nbsp; &nbsp; :m_str(str)&nbsp; &nbsp; {}&nbsp; &nbsp; std::ostream& m_str;};// New Format Objectstruct PutSquareBracket{};// Format object passed to stream.// All it does is return an object that can maintain state away from the// stream object (so that it is not STICKY)SquareBracktAroundNextItem operator<<(std::ostream& str,PutSquareBracket const& data){&nbsp; &nbsp; return SquareBracktAroundNextItem(str);}// The Non Sticky formatting.// Here we temporariy set formating to fixed with a precision of 10.// After the next value is printed we return the stream to the original state// Then return the stream for normal processing.template<typename T>std::ostream& operator<<(SquareBracktAroundNextItem const& bracket,T const& data){&nbsp; &nbsp; std::ios_base::fmtflags flags&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= bracket.m_str.flags();&nbsp; &nbsp; std::streamsize&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;currentPrecision&nbsp; &nbsp; = bracket.m_str.precision();&nbsp; &nbsp; bracket.m_str << '[' << std::fixed << std::setprecision(10) << data << std::setprecision(currentPrecision) << ']';&nbsp; &nbsp; bracket.m_str.flags(flags);&nbsp; &nbsp; return bracket.m_str;}int main(){&nbsp; &nbsp; std::cout << 5.34 << "\n"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Before&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; << PutSquareBracket() << 5.34 << "\n"&nbsp; // Temp change settings.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; << 5.34 << "\n";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// After}> ./a.out&nbsp;5.34[5.3400000000]5.34
打开App,查看更多内容
随时随地看视频慕课网APP