Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2001-12-20 17:23:33


 
> This is not so different really from cout << format << args
> operationally, though I agree it is clearer syntactically. In either
> case you have a new stream-like object.

Yes, but it is stream like enough ulike the original complaint
that "it looks like a manipulator but doesn't act like one."
 
> There are two things I would worry about:
>
> 1) The conceptual binding of the format and the stream. The format
> really should be a distinct object, IMHO, since you should be able to
> apply the same format to several different output streams. But that's
> not so hard to deal with by using instead two constructors:
>
> formatter::formatter(ostream &, format const &)
> format::format(char const *); // Note not explicit...
> format::format(string const &); // Completeness...
>
> So I think this is not really an issue, just a nit with the way you
> wrote it originally.

I was thinking more of
  class format_stream { /* ctors */};

  format_stream format(ostream& os, const char* str)
    { return format_stream(os, str); }

Thus allowing reuse by...

  format_stream fout(cout,"%d %d\n");
  for (i=0;i<10;i++)
    {
      fout << a[i] << b[i] << endf;
    }

It would also be nice if it could take the parser as a template argument.

==============
template <class T_char, class T_trait, class T_format>
class basic_format_stream {....};

typedef basic_format_stream<char,trait<char>,reorder_parse<char,trait<char> > >
   reorder_stream;
typedef basic_format_stream<char,trait<char>,printf_parse<char,trait<char> > >
   reorder_stream;
=====

  reorder(cout,"%1 %2") << a << b;
  format(cout,"%1$s %2$s") << a << b;

I am sure there are a number of alternatives. I think one of my
basic problems is formating means more than reordering so naming
something "format" better do formatting. If you want to just do
reordering and have some abreviated syntax it better not be a
"format".

> 2) The returned value may be a stream, but it is *not* a basic_ostream
> (obviously enough once you think about it). So it cannot be passed to
> functions which expect an ostream as an argument.

No, it certainly can not. (Not unless someone comes up with a really
cleaver solution.) But it is beyond my skill.

> I don't think this is really a problem either, though it needs to be
> clearly documented. The only cases I could think of where ostream is
> passed as an argument are either handled correctly (eg, polymorphic
> printing through a single operator<<(Base &) and virtual member), or
> aren't something that could work anyway and will die with compile
> errors (passing the stream to a function doing output, expecting the
> output to be formatted per the format).
>
> But, I thought I would mention it in case someone else could think of a
> case where it's a problem.
>
> So I think this is a valid approach. I think it is cleaner syntax-wise than e
> ither of the other options, avoids the template expression machinery, allows
> some optimizations without too much of a headache... In general, I think I li
> ke it.
>
> Can this be made to work to replicate scanf (with constant strings inside it)
> as well? I think it can, though I think there's less call for scanf...

Yes, it is certainly possible, though the frequency at which that
would like get used is low.

--Karl


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