Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2000-08-19 11:43:41

> I'll confess: I issued the original challenge which resulted in Rudiger's
> contribution. One of my big complaints with printf is that I find the format
> specifications impossible to remember, so a goal was to come up with
> something much simpler. Another issue is that printf specifiers always
> indicate something about the type of the argument to be formatted, which is
> completely unneccessary with typesafe C++. I notice you cover that by
> allowing %s to format *anything*, not just a string.

Yes, that is a definite difference in strategies. My general philosophy
has always been strict adherence to a standard even if it is poor is
better than cutting something yourself. However, this is very open for

Now in regards to mine. The prinf specifiers are made very fuzzy.
%s means any literal. %d means anything with the decimal formatted.
%x means anything with numbers printed as hex. Thus the print
indicators are more about how shall I format this and not really what
type the item is.

> > He does add some fancy things
> > like centering that mine lacks because those aren't in printf specs.
> > However, his format caps the number of arguments to the
> > format command at 9 arguments. Mine code caps out at around 256
> > because more than that was kind of pointless.
> I'm not sure how compelling it is to be able to format more than 9
> arguments. One upside of the boost system is that it is clear exactly which
> arguments go with a particular format string.

It certainly is not very compelling as I could count on one hand all
the times I had more than 9 arguments (though I can remember it happening).
A more direct problem is that I think that the current implementation
may always require pass by value. Thus you must specialize each
subset of const T& and T& for a given number of arguments.

Thus for 4 arguments you would need
  T&, T&, T&, T&
  const T&, T&, T&, T&
  T&, const T&, T&, T&
  T&, T&, const T&, T&
  T&, T&, T&, const T&
  const T&, constT&, T&, T&
  T&, const T&, constT&, T&
  T&, T&, const T&, constT&
  T&, constT&, T&, const T&
  const T&, T&, T&, const T&

Okay you get the point. I have tried something similar for
a general create template, when I was trying to make new private
for a class by allow GC for items through create.

The problem comes down to C++ needs a
  template <class T&> foo(T t);
which means T is always a reference type.
Without this anything which tries to do format(...) with templates
will fail.

> > His is coded in charT templates. Mine is currently only 8
> > bit form. Although this is interesting I am
> > not sure how applicable it is to a UTF-8 stream. UTF-8 is exactly
> > that 8 bits (with variable length encoding.) I assume mine could be
> > changed but the details of the interactions would likely need to be
> > discussed.
> For some of us, being able to handle wide characters (unicode) was an
> important design criterion.

Yes. I agree. I just don't know that I would be qualified to extend
my stream properly to cover that meaning. It is a large can of
worms. I would tend to believe that my format should just be
overloaded for wide uses or charT specials and leave the default
something like this. wformat???

> > Mine is passed on a stream proxy, so it looks like a manipulator.
> > His is designed to look like a function.
> I think if you review the boost discussions, you'll see that I suggested
> this as a way of keeping the format string associated with its arguments as
> described above.

Right. I did notice that. But it wasn't discussed why
making the format a normal manipulator was bad.

> > Other manipulators do
> > not count as arguments in my. They do in his.
> Yes, I don't love this arrangement. Actually, I don't mind having the
> feature, but for ease-of-use I would prefer to see a different form of
> manipulators which enclosed the argument to which they applied. For example:
> boost::format("%1 != %2", fixed(boost::setprecision(5, 1.9999)), 2.0000);
> where fixed and setprecision(5) are being applied only to 1.9999 above.

Well mine of course escapes that unless you want variable width

 cout <<format("%.5f != %f") << 1.9999 << 2.0000;

(whether this is implemented properly currently is open to question.
I was still early in the testing.)
> > His as functions
> > has ordering preferences, mine being a stream can not.
> I don't understand what you mean by "has ordering preferences".

format( foo, bar ) has a clear start and stop because (). Mine
is quite fuzzy, though endf serves that purpose.

> I think one of the biggest problems with Rudiger's examples is that he
> overstresses complex capabilities like nested formatting, which makes them
> hard to read. AFAICT, your example would not produce equivalent output to
> his. I think to get something equivalent to your example, we could write:

Yes, I know mine wasn't exactly equivelent. But then by following
printf mine sort of has to be non-equivelent. I am not at all
opposed to adding some char like <>^ to indicate alignment and such.

> std::cout << format("The Truth is %3%4%1 != %2\n",
> format("%3%4%1 != %2", 1.9999, 2.000, setprecision(5),fixed));
> > There would be no way in mine to cap the size of the two arguments
> > and center them. On the other hand standardizing how to
> > center "1000.0000 != 10000.0000" if they came out to more than the
> > recommended field length seems difficult at best. Something
> > so fancy probably should be left to the user who would
> > code to drop precision over accidentally saying
> > "1000.0000 != 1000".
> I think the boost strategy is to blow off the formatting if the value
> representation would be overly compromised. I think this is the same thing
> that printf does with field widths. I'm not positive, though.

Printf blows off widths in this case. Hopefully mine can do the same.
I am not sure about boost format.


Boost list run by bdawes at, gregod at, cpdaniel at, john at