可能重复:
“Roll-Back” or Undo Any Manipulators Applied To A Stream Without Knowing What The Manipulators Were
考虑以下代码
int temp=256;
cout<<temp<<endl;
cout<<hex<<temp<<endl;
cout<<temp<<endl;
输出分别为“256”,“100”和“100”。 是否可以使'hex'标志不具有约束力?
我不想明确地写'dec'。
答案 0 :(得分:2)
不适用于标准操纵器。但在实践中,你可能 不应该使用标准操纵器(除了可能作为一个 例);它们对应于物理标记,在应用程序中,您 想要使用逻辑标记。你想写类似
的东西cout << temperature << roomTemperature;
,其中温度是特定应用的操纵器,定义 (全球)如何输出温度。那样的话,如果 规格变化,需要不同的温度格式, 你只需要在一个地方改变它。调试输出有点 这里有一个例外,但即使在那里,写起来也容易得多 类似的东西:
cout << HexFmt( 4 ) << var;
大于
cout << hex << setfill( '0' ) << setw( 4 ) << var;
(你可能经常使用像HexFmt
这样的东西
证明在工具箱中使用它。)
你自己写的机器人可以恢复 以前的状态,至少在完整表达结束时。我所有的 操纵者来自以下类:
StateSavingManip.hh:
class StateSavingManip : boost::noncopyable
{
mutable std::ios* myStream;
mutable std::ios::fmtflags
mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
private:
virtual void setState( std::ios& stream ) const = 0;
protected:
StateSavingManip();
public:
StateSavingManip( StateSavingManip const& other );
virtual ~StateSavingManip();
void operator()( std::ios& stream ) const;
};
inline std::ostream&
operator<<(
std::ostream& out,
StateSavingManip const&
manip )
{
manip( out );
return out;
}
inline std::istream&
operator>>(
std::istream& in,
StateSavingManip const&
manip )
{
manip( in );
return in;
}
StateSavingManip.cc:
namespace {
int getXAlloc();
int ourXAlloc = getXAlloc() + 1;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1;
assert( ourXAlloc != 0 );
}
return ourXAlloc - 1;
}
}
StateSavingManip::StateSavingManip()
: myStream( NULL )
{
}
StateSavingManip::StateSavingManip(
StateSavingManip const&
other )
{
assert( other.myStream == NULL );
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != NULL ) {
myStream->flags( mySavedFlags );
myStream->precision( mySavedPrec );
myStream->fill( mySavedFill );
myStream->pword( getXAlloc() ) = NULL;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() );
if ( backptr == NULL ) {
backptr = const_cast< StateSavingManip* >( this );
myStream = &stream;
mySavedFlags = stream.flags();
mySavedPrec = stream.precision();
mySavedFill = stream.fill();
}
setState( stream );
}
这允许简单的事情:
class HexFmt : public StateSavingManip
{
int myWidth;
protected:
virtual void setState( std::ios& targetStream ) const
{
targetStream.flags( std::ios::hex | std::ios::uppercase );
targetStream.width( myWidth );
targetStream.fill( '0' );
}
public:
explicit HexFmt( int width )
: myWidth( width )
{
}
};
答案 1 :(得分:1)
使用Boost I/O Streams-State Saver Library:
int temp=256;
cout<<temp<<endl;
{
boost::io::ios_flags_saver saveflags(cout);
cout<<hex<<temp<<endl;
}
cout<<temp<<endl;
答案 2 :(得分:0)
没有。不,这不对。 hex
坚持。