Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2002-01-29 16:32:59


> > From: Karl Nelson [mailto:kenelson_at_[hidden]]
> >
> > Why should their be persistent manipulators in a format stream.
> > They don't make sense because they can get moved up when reordered.
>
> Persistent manipulators allow for useful factorizations. If you are about
> to output 5 numbers, and you want them all as hex, it is convenient to only
> have to specify hex once.
>
> Likewise, persistent manipulators help with generic code. For example:
>
> void myclass::print_numbers(ostream& os, format& fmt) {
> for (int i = 0; i != end_; ++i)
> os << fmt[numbers_[i]];
> }
>
> void caller() {
> format fmt("--[1]--")(hex);
> the_instance.print_numbers(cout, fmt);
> }
>
> Of course, in this simple example, hex wouldn't have to be specified as a
> manipulator, but you get the point. There is power in passing a pre-cooked
> format object into an output function.

This looks more like formating reuse. I don't see this a presistent.
What is wrong with this?

 void myclass::print_numbers(ostream& os, format_expr& fmt) {
   for (int i = 0; i != end_; ++i)
     os << format(fmt, numbers_[i]);
 }

 void caller() {
   format_expr fmt("--%x--");
   the_instance.print_numbers(cout, fmt);
 }

> > Consider if I allow persistent manipulators and just have a simple
> > reorder stream.
> >
> > cout << format( fstr) % 16 % hex % 16;
> > Okay so if fstr is "[1] = [2] base 16" thus we print
> > "16 = 10 base 16". But if manipulators are persistent if
> > someone attempts to reverse the order in some translation they
> > write "[2] ???? 16 = [1]", this implies
> > cout << hex<<16 " ???? 16 = " << 16;
> > Thus we print "10 ???? 16 = 10". Ouch, not what we want.
>
> It depends on the persistence semantics that are in force. I wouldn't
> recommend using the semantics you assume for this example. The manipulator
> should apply to all subsequent arguments, regardless of their placeholder
> position. Then the example would come out fine.

Still a hard call. You would have to know that hex should
be sticky and apply it to every stringstream after that point.
 
 
> > > Only the %d confuses the issue. I would expect the %d to
> > be applied to each
> > > argument, meaning for c=3 you would get: " Change is 433".
> > This is a good
> > > example of why is it best of avoid type specifiers unless
> > you really want to
> > > override the current format specified by the manipulator
> > context (e.g.
> > > override decimal with hex or vice verse).
> >
> > I take this argument a completely different way. Yes, type
> > specifiers
> > should not convert types, but rather they simply should not be taken
> > as literial.
> >
> > I take the type as being very general.
> > x - stream is hex (any numbers in it are shown as hex)
> > d - stream is decimal (any numbers in it are shown as decimal)
> > s - string literal (stream defaults)
> >
> > Thus %d on group(c>0?'+':'-',c) is "<< dec << '+' << 3".
> >
> > We don't try to convert the argument. It is also almost impossible
> > to do because, we would have to force the types to fix basic types
> > to interpret them.
>
> I agree that format should not be in the business of type conversions.
> "char" is ambiguous in terms of how it should be represented (kind of like
> bool with "0" or "false"). I can see value in
> manipulators/format-specifiers that allow specification of how char is to be
> displayed.

Isn't placing something into a stream automatically a method of char
conversion? All that the type specifiers do is govern how the conversion
is done. Unfortunately, to do a "good" job of defining a universal
format string is strictly limited to what you can do with ostream and
and what you can do with the post conversion string.

 
> However, it doesn't make sense to gratuitously include such. The problem is
> that if there is a mismatch, as you are proposing char and %d would be,
> format has to do something about it. It can throw or silently fail, where
> "silently fail" means display in the default rendering for that type. Each
> option is wrong in some cases. Why make the code author respecify the type
> that the compiler already knows perfectly well?

It doesn't know how the user wants it printed. What base, what precision,
should it be scientific or fixed?

> In the case of templates,
> the compiler knows it better than the author. I just don't see what value
> there is in specifying a type in the placeholder. Changing the formatting
> within the class of formats for a given type is fine. But just a type
> specification with no (desired) effect, I don't understand.

You are trying to make this do conversions again rather than just
specify formatting conversions.

--Karl


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk