为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
aluckdog 2019-07-17 10:24:53
哪个自吹自擂的操纵者是“粘性”的?最近我在创建一个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)似乎没有清楚地显示这一点。
查看完整描述

3 回答

?
红颜莎娜

TA贡献1842条经验 获得超12个赞

以下评论的重要说明:

马丁:

@Chareles:那么根据这个要求,所有的机械手都是粘性的。除了SET,它似乎在使用后被重置。

查尔斯:

一点儿没错!而setw似乎行为不同的唯一原因是,格式化的输出操作需要显式地.Width(0)输出流。

以下是导致上述结论的讨论:


查看代码,以下操作程序返回一个对象,而不是流:

setiosflags
resetiosflags
setbase
setfill
setprecision
setw

这是一种将操作应用于仅应用于流的下一个对象的常见技术。不幸的是,这并不能阻止他们粘在一起。测试表明,除了setw粘粘的。

setiosflags:  Stickyresetiosflags:Stickysetbase:      Stickysetfill:      Stickysetprecision: Sticky

所有其他操作器都返回流对象。因此,它们更改的任何状态信息都必须记录在流对象中,因此是永久的(直到另一个机械手改变状态)。因此,下列机械手必须是操纵者。

[no]boolalpha[no]showbase[no]showpoint[no]showpos[no]skipws[no]unitbuf[no]uppercase

dec/ hex/ oct

fixed/ scientific

internal/ left/ right

这些操纵器实际上对流本身执行操作,而不是对流对象执行操作(尽管从技术上讲,流是流对象状态的一部分)。但我不认为它们会影响流对象状态的任何其他部分。

ws/ endl/ ends/ flush

结论是,在我的版本中,setw似乎是唯一不粘的操纵者。

对查尔斯来说,一个简单的技巧就是只影响链中的下一个项目:
下面是一个示例,说明如何使用对象临时更改状态,然后通过使用对象将其放回原处:

#include <iostream>

#include <iomanip>


// Private object constructed by the format object PutSquareBracket

struct SquareBracktAroundNextItem

{

    SquareBracktAroundNextItem(std::ostream& str)

        :m_str(str)

    {}

    std::ostream& m_str;

};


// New Format Object

struct 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)

{

    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)

{

    std::ios_base::fmtflags flags               = bracket.m_str.flags();

    std::streamsize         currentPrecision    = bracket.m_str.precision();


    bracket.m_str << '[' << std::fixed << std::setprecision(10) << data << std::setprecision(currentPrecision) << ']';


    bracket.m_str.flags(flags);


    return bracket.m_str;

}



int main()

{


    std::cout << 5.34 << "\n"                        // Before 

              << PutSquareBracket() << 5.34 << "\n"  // Temp change settings.

              << 5.34 << "\n";                       // After

}



> ./a.out 

5.34

[5.3400000000]

5.34


查看完整回答
反对 回复 2019-07-17
  • 3 回答
  • 0 关注
  • 495 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信