Boost logo

Boost :

From: Samuel Krempp (krempp_at_[hidden])
Date: 2001-12-19 17:23:45


On Wed, 2001-12-19 at 21:11, George A. Heintzelman wrote:

> int arg;
> cout << format("String here: %1") *op* arg;
>
> Ideally, I would like to see the following stream calls resulting:
>
> operator<<(cout,"String here: ");
> operator<<(cout,arg);

That would be great, but I gave up this ideal very quickly, because of
"positional arguments".
cout << format("%3 %2 %1 %2 %3") % x % y % z;
Either you use a temporary stringstream, and dump the final string to
the destination stream,
or you store all variables in a list,
then dump them directly to destination stream.

I tried the second approach, and I quickly gave up, the run-time
polymorphism implied by this "list of all variables" made things ugly,
and lead to many problems.

On the other hand the temporary stream's impact on performance is not
too bad, just a few extra copies.

I benchmarked the performance of format vs the equivalent, minimal
stream operations : it was 2.6 times slower, if compiled with
optimisation. Without optimisation, the ratio grows to 5.
That's acceptable, no ?

> Again ideally, I would rather not see the following sequence:
> stringstream(tempstr);
> operator<<(tempstr,"String here: ");
> operator<<(tempstr,arg);
> operator<<(cout,tempstr);
>
> I think that with the choice of %, you're essentially forcing the
> implementation to do things with a temporary buffer internally, and
> thus copy arguments.

Yes, that's right.
but we don't really have a choice, trying to avoid those copies has more
drawbacks than advantages.
And anyway, sometimes it is necessary, when you want to get a string as
a result of the formatting (instead of dumping directyl to a stream)

> Second, I think this choice impacts how a formatter object can be used.
> Since I expect the formatter constructor to do some parsing work, I
> would like to be able to do something like:
>
> void print_three(ostream &os, int x, int y, int z) {
> static const format("X: %1 Y:%2 Z:%3");
> os << format << x << y << z;
> }
>
> Which might be fine for ints in the current setup -- but not if,
> instead of an int, I used a recursive data structure whose operator<<
> itself called print_three.

Okay, I see what you mean.
if you expect recursive calls, avoid this... feeding arguments into a
format object is not a const operation, and I believe it would be hard
to make it be so.
Still, you can do the parsing only once and store it in a static object:

void print_three(ostream &os, int x, int y, int z) {
   static const format parsed_format("X: %1 Y:%2 Z:%3");
   format fmter = parsed_format;
   os << fmter % x % y % z;
}

> IOW, I think I am objecting to the format object carrying the
> combination of the basic format string and simultaneously the arguments
> being formatted. I ought to be able to have one format object, and
> several different objects which reference that format with different
> arguments. Maybe I want to bind one of those arguments down, and then
> copying that bound object to make a format binding with 1 less arity.

Maybe I read this too quickly, but I think you can do that currently
with my class. A format object, right after creation, only holds the
data from the format-string. You can keep it, copy it and feed arguments
to the copy. (You don't need to copy, but it won't be const then. the
state of the object would evolve in cycles : full of arguments / dumped
/ full of arguments / dumped / etc..)

It's just that you wished that arguments were decoupled from the rest ?
 
> Hmm. This whole thing is starting to seem reminiscent of the bind
> library. Can't we express this whole format idea using bind on
> operator<< (except that the order of the bindings are specified by a
> string instead) ? Maybe we should look back at the bind library for
> some ideas.

You're beginning to make me curious about the bind library. I dont
recall exactly what made me think the first approach (storing a list of
variables) was a dead-end. Maybe some things that I thought infeasible
are in fact possible, and solved in this library.

I'll look at it, and then I'll tell you if I think it can lead to
something or not, for a format class.

regards,

-- 
Samuel

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