Boost logo

Boost :

From: Samuel Krempp (krempp_at_[hidden])
Date: 2001-06-29 13:46:42


> * The choice of arithmetic operators "*" and "%" is totally unsettling to
> my eye. Let's try it with "<<":

oh, you really dont like it at all ??
well, I took % and * because it has some advantages..
at every of the points stated below, the
"2-operators" approach yield a simple solution.

They have the same precedence, which is higher than '<<' (and that's the
only important thing in their choice)..

> << internal << setfill('W') << 234
> << internal << setfill('X') << -345

The problem here, is that I could not find a way to distinguish those
manipulators from another object

setfill(10) is of type setfill, setprecision(3) has another type, etc..
The only thing I came up with is to use a wrapper class, actually
implemented like that :
cout << glue(internal) << glue(setfill('X')) << 234
But typing glue everywhere quickly gets tiresome..

So having a specific operator to mean
"the following argument is a manipulator" is very practical, and I dont
see another way, unless someone tells me how to partial-specialize or
overload the operator<< to distinguish manipulators from the rest.

Another direction was to define boost's own manipulators,
either as object encapsulaters "hex(x)" [not great to have all those
parenthesis when we use several manipulators ]
either as standalone objects very similar to std's but all expressed as
templates so as to enable specialisations like :
template<int n>
operator<<( const manip<n>& f);

With the "2-operators" amethod, operators * and % make it possible to
specify which behaviour (manipulator eating or real variable) whatever
their types, and it's a real flexibily advantage.

BTW, if we want the same "2-operators" behaviour but using operator<<,
the second one is necessrily operator>>, because precedence matters.
it's a bit confusing to see :
cout << format("%s %s %s")
>> setfill('X') << 1 << 2 >> hex >> showbase << 3;

so, with all those considerations, operators % , * seemed like the best
choice to me..

> * Having a disappearing argument ("invisible extra argument") seems like a
> bad idea; most likely it is a coding error so should not be silent, IMO.

I dont know. Unix98 printf explicitly has this behaviour.
So this decision depends on how much we want to respect printf's
specification.

Maybe it is here to allow for arrays of format strings, intended to
format the same arguments with varying verbosity..
say
std::vector<string> msgs;
int verb=3;
....
cout<<format(msgs[verb]) %x %y %z %var1 %var2;
So the same line of code can give different levels of detail.

but well, I really dont have a strong opinion on this, so we should
find which behaviour the majority wants about extra arguments.

Anyway, in the case of a single operator, the best is clearly to expect
exactly enough arguments.
else we have to use a marker if we want to continue using the stream after
the format, like :
cout << format("point1 : %s %s") << x1 << y1 << endf
        << "and point2 is "<< x2 << y2;

> * Like Dave (in another message), I really hate sticky formatting; it has
> caused me a lot of past grief.

I followed Dave's opinion, so nothing here is sticky.

by the way, I updated the files at least 5 times today (for slight
changes, but..), so to be sure you have the lates, you have to look at the
version number displayed in the files vault.

-- 
Sam

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