basefield is the mask for the bits that determine the base to use for
I/O. If you just setf(ios::hex) you jam in whatever value ios::hex has,
and might end up with an invalid flag setting. When you use
setf(ios::hex, ios::basefield) you clear the bits represented by
basefield, then jam in the value of ios::hex.
In general, you need to do the analogous thing with all of the flags
that have more than two values.
You mean, with all of the flags which aren't flags
. And of
course, std::ios::hex only has one value, at least in a given
implementation.
The way I think of it is that fmtflags is conceptually a struct.
Some of the fields are boolean (flags), and can be set and reset
using the single argument versions of setf and unsetf. There is
no separate mask value (i.e. no ios::showposmask) for these,
since the set value is the mask (supposing you needed a mask).
Others, such as the base, the floating point representation, and
the alignment, are conceptually enum's: these have a distinct
mask value (field name), and can only be manipulated using the
two argument form of setf, with the name of the field as the
second argument.
Note that in the two argument form, you must specify all of the
affected fields in the second argument. Just saying:
setf( ios::showpos | ios::hex, ios::basefied )
isn't sufficient---you have to say:
setf( ios::showpos | ios::hex, ios::showpos | ios::basefield)
IMHO, however, it's clearer if you use two separate function
calls for this.