Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2000-08-19 13:46:06

> > 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
> > debate.
> >
> > 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.
> Okay, that's pretty easy to remember, but of course it doesn't exactly
> correspond to the 'C' standard for printf. Whether it is a good idea to do
> something which is reminiscent of a standard but does not strictly adhere
> is, I think, open to argument.

It is more than reminiscent in that if you place the arguments in
as the type that the indicators describe you will get exactly what
tyou expect. It is just the what happens if the type modifiers
don't match which is quite different. I think just making
the format assume best possible interpretation rather then a
segfault is best. (ie, "you told me to expect a hex int but gave me
a some other type, I guess I will just set the hex flag and let you deal
with the output.")

This is actually really nice for things like complex types going
to %f or %e.

(Note, this is quite different from the streamprintf code someone
posted. There they were trying to impose some meaning on the indicators.)

> Okay, so 2^9 is "only" 512 signatures... ;)

Actualy 2&9+2^8+2^7+2^6 ... because we will want all the signature
combinations below.

> > 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.
> Yes, but I don't think that really applies in this case. There really is no
> excuse for modifying an argument to output formatting, is there?

It does actually, because otherwise you are forcing all types to have
a T(const T&). Many classes this may be expensive or perhaps not
the intended meaning. Thus by forcing copy by value you have no options.

Another problem is the hidden cost of using templates. That is every
set of arguments will need to implement a new function. Thus
share nothing. This could get to be a very large number of functions
for compilers that don't inline and possibly worse very large code
for those that do.

> > 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.
> Oops, you lost me with this part.

If C++ wanted to deal with this problem they would allow specifications
in the template type. Thus rather then having to define

  template <class T1, class T2, class T3>
    void foo(T1& t1,T2& t2,T3& t2) {bar(t1,t2,t3);}
  template <class T1, class T2, class T3>
    void foo(const T1& t1,T2& t2,T3& t2) {bar(t1,t2,t3);}
  template <class T1, class T2, class T3>
    void foo(T1& t1,const T2& t2,T3& t2) {bar(t1,t2,t3);}
  template <class T1, class T2, class T3>
    void foo(T1& t1,T2& t2,const T3& t2) {bar(t1,t2,t3);}

when I just want to proxy arguments through, I could could
define something like...
  template <class &T1, class &T2, class &T3>
    void foo(T1 t1,T2 t2,T3 t2) {bar(t1,t2,t3);}

which would load all combinations of reference types.

But honestly unless I suddenly because all power C++ lord and
master and could magically control committee members with my
mind it isn't going to happen. :-)

> > > 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.
> It shouldn't be too much of a challenge, AFAICT.

Well, it will be a challenge for me because the current compilers
I target (gcc, egcs) don't have charT streams yet. :-)

> > 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???
> Whoops, I'm lost again.

Just saying that rahter then going for the full charT specification,
writting my class for ostream and wostream would likely cover 95%
of all users. Assuming STL gets implemented better in GNU world,
a charT version could be made.

> > > 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.
> I don't think it's bad, but it may be impossible to do with ordinary
> streams. After all, a normal manipulator is a function. I think format() has
> to carry state with it.

Well I was targetting to make as close to a manipulator
as I could. Since "hex" affects arguments after it, I expect
format to do the same. Although this isn't nearly as easy to acomplish
as one might hope. Mine should do an okay job of hiding that it isn't.

About the only difference between what I implemented a normal manipulator
is mine doesn't carry through line breaks.

  cout << format("%d %d") << i;
  cout << j ; // sorry format was already closed.

Really though I think that the template one is a show stopper and
thus manipulators are much more likely to work. After all streams
take one item at a time.

> > Well mine of course escapes that unless you want variable width
> > specifiers.
> >
> > 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.)
> The problem with this is that normally you want manipulators to be
> associated with the arguments to be formatted. Normally, the choice of
> manipulations won't be affected by i18n issues (I think). So putting it in
> the format string may be the wrong choice.

True, but placing there helps to match the standard and does
not in any way prevent the use of other normal manipulators. For
example (assuming we want to make state restoring between arguments)...

cout << format("%f %.3f %f") << precision(5) << a << b << c;

would place b with precision 3, a with precision 5, and c with
whatever the stream default is.

In mine were not state restoring then

cout << format("%f %.3f %f") << precision(5) << a << b << c;

means a and c get precision 5, b is overwritten to 3. THe problem
with this being life gets confusion with rearranging. a,b,c get
same formating as before but show up in different order.


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