Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2000-08-21 22:44:49


----- Original Message -----
From: "Karl Nelson" <kenelson_at_[hidden]>
> > One other question: is it really neccessary to have a separate format()
and
> > string_format() in the usage syntax? It seems (without looking at the
> > details) like you could make the following work:
> >
> > cout << format("The Truth is %^20s\n")
> > << (format("%f != %f") << 1 << 2);
> > cout << format("The Truth is %^25s\n") << setfill('.')
> > << (format("%.5f != %f) << 1.9999 << 2.000 );
> >
> > The key is that you can have separate return types (X and Y) for
> >
> > X operator<<(ostream&, const <type-of-format>&)
> >
> > and
> >
> > template <class T>
> > Y operator<<(const <type-of-format>&, T)
>
> I did think about this one a bit but decided to propose
> the string_format() instead.
>
>
> > Am I onto something here or am I speaking from a "dark place"?
>
> This isn't a dark place, but rather just a bit of ambiguity.
> My current implementation used two formats in a row to mean
> "dump current and use this one". However, that functionality
> could be dumped in place of the other meaning.

I don't think that's neccessary. There shouldn't be any ambiguity. The
parenthesized expression:
   (format("%f != %f") << 1 << 2)
would have a return type Y which, when streamed, would perform the
formatting, whereas the expression:
    cout << format("The Truth is %^20s\n")
would have a return type X. In your case, X is ofrstream. In my suggestion,
type Y would probably be a wrapper around std::ostringstream<>.

> Also one would have
> to ask is the current behavior that extra arguments are placed
> in the stream appropriate as well.
> cout << format("%d %d") << i << j << format("%d %d") << k << l;
>
> (is the second format bad because the first one forgot the endf
> or should the second flow to the first?)

Just keep in mind that the above expression could be completely different
from:

cout << format("%d %d") << i << j << (format("%d %d") << k << l);

Although they might produce the same result, depending on what you decide
about the above questions.

In fact, one way to handle the grouping of format arguments in this case
might be to establish the following usage:

cout << (format("%d %d") << i << j) << (format("%d %d") << k << l);

This expression streams two Y objects into cout. There would be 2
operator<<() instances that take a Y rhs:

ostream& operator<<(ostream&, const Y&);
ofrstream& operator<<(ofrstream&, const Y&); // unused in the example above

Each of these could check that all arguments specified by the format string
had been supplied.

> Note that I could achieve the same thing you describe by
> just making a conversion from format to string, this would give....
>
> format::operator string(); (or basic_string for template version.)
>
> cout << format("The Truth is %^25s\n") << setfill('.')
> << string(format("%.5f != %f) << 1.9999 << 2.000 );
>
> Which actually is a bit more meaningful. (take a format
> and make a string for use on the first format statement.)
>
> Is that acceptable?

The idea of introducing an implicit conversion worries me. I'd much rather
see something a bit more like what I'm proposing.

-Dave


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