Как правило, вы не используете стандартные манипуляторы напрямую. В
В этом случае, например, вы можете определить манипулятор
fromVector, и используйте это:
output << '['
<< fromVector << v.x << ", "
<< fromVector << v.y << ", "
<< fromVector << v.z << ']';
Таким образом, если вы хотите изменить ширину и точность
элементы в векторе, вам нужно сделать это только в одном месте.
В этом случае, когда у манипулятора нет аргументов, все это
нужна простая функция:
std::ostream& fromVector(std::ostream& stream)
{
stream.setf(std::ios::right, std::ios::adjustfield);
stream.setf(std::ios::scientific, std::ios::floatfield);
stream.precision(16);
stream.width(32);
return stream;
}
Конечно, это изменит большую часть форматирования для любого
позже пользователь. В общем, было бы лучше использовать
временный объект класса, который сохраняет состояние и восстанавливает его
в деструкторе. Я обычно получаю свои манипуляторы от
что-то вроде:
Заголовок:
Класс StateSavingManip
{
общественности:
StateSavingManip (
StateSavingManip const & other);
virtual ~StateSavingManip() ;
void operator()( std::ios& stream ) const ;
protected:
StateSavingManip() ;
private:
virtual void setState( std::ios& stream ) const = 0 ;
private:
StateSavingManip& operator=( StateSavingManip const& ) ;
private:
mutable std::ios* myStream ;
mutable std::ios::fmtflags
mySavedFlags ;
mutable int mySavedPrec ;
mutable char mySavedFill ;
} ;
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 ;
}
Источник:
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 ) ;
}
Если вы сделаете это, вам нужно будет добавить скобки после
манипулятор, например ::
output << '['
<< fromVector() << v.x << ", "
<< fromVector() << v.y << ", "
<< fromVector() << v.z << ']';
(Я уверен, что какая-то умная душа найдет способ
избегая их, но они никогда не беспокоили меня, поэтому я не
беспокоили.)