Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-02-25 18:57:13


>From: "Jason House" <jhouse_at_[hidden]>
> >
> > std::vector<std::pair<char,int> > test;
> >
> > std::cout << test: // Using defaults
> >
> > (('A',1),('B',2),('C',3))
>
> I would suspect that chars don't get output with '' around them...

Right. I was just thinking C++ code, here. :)

> Is there even a way to specify/change that?

It isn't currently, as the fundamental types aren't handled as composite
types, and therefore aren't formatted using any set format. Also, it seems
it may not be possible in an obvious way. For example, the following
addition to the header doesn't work:

template<class CharType,class CharTraits>
std::basic_ostream<CharType,CharTraits> &operator<<
  (std::basic_ostream<CharType,CharTraits> &stream,char value)
{
  typedef basic_composite_format<CharType,char> format_type;

  const format_type &format=format_type::format(stream);

  stream << format.start;
  stream.operator<<(value);
  stream << format.end;

  return stream;
}

It appears to prefer the operator<<(char) stream member function, to this
free function, as it isn't called when doing "std::cout << 'A';".

> > In this case, it's not possible to set the format for each type
separately.
> > Maybe it could be good to keep that feature of the current composite
> > operators, as well, something like:
> >
> > typedef std::pair<char,int> map;
> > typedef std::vector<Map> map_list;
> >
> > map_list test;
> >
> > std::cout << io::set_delimiter<map>("\n") << test;
> >
> > Output:
> >
> > (('A',1)
> > ('B',2)
> > (C,3))
>
> so basically, you would like to combine tuple-like output specification
> (ie for all tuples) and type specific such as composite_format?

I was thinking of that, yes. As well as a default, possibly user-settable,
for any type not having set an explicit format. This would let you control
the formatting in layers, so to speak:

- You could use/set the default format for all types.
- You could use/set the format for all instantiations of a given template,
e.g. std::vector.
- You could use/set the format for specific types.

If possible, it would apply the most specific format set (i.e. it would
prefer 3 to 2, to 1).

Another thing is if this layering is practically possible. :) We get into
this below here.

> > template<class CharType, class CharTrait, class T1, class T2>
> > inline std::basic_ostream<CharType, CharTrait>&
> > operator<<(std::basic_ostream<CharType, CharTrait>& o,
> > const cons<T1, T2>& t)
> >
> > As you say, this may be a problem to call from a debugger, unless it
> > supports calling function templates. If one need to call it from a
debugger,
> > one could always wrap the code in a function.
>
> :(
> Debugger friendly manipulation would be good. I still haven't thought
> about how exactly outputting of an arbitrary composite variable will
> work in the debugger by default... I agree that having a wrapper makes
> it easy for the output formatting of general types, but actually being
> able to execute "std::cout << my_suspect_variable" in the debugger
> without premeditation still poses a significant problem. Why can't bugs
> be predicted before you notice them?

You're right, good point. Would it be possible to get some information on
what kind of functions, if any, may be called in e.g. your debugger? From
this, we may find what we can do.

> > There was a suggestion for allowing generic formats, though, using
> > the same format for all instantiations of a template. The question is
how to
> > do it. The current version stores the format for each specific type, as
you
> > say. Volodya suggested a couple of ways it could be done, partial
> > specialisation, or storing the template name in a map. However, it could
be
> > hard to use the latter, as it could be hard to find the right type to
look
> > up, when outputting, given that you have specific types, not templates.
> >
> > Overloading of class templates might have helped, here. E.g.:
> >
> > std::cout << io::set_format<std::vector<std::pair<char,int> >(...); //
Set
> > specific format (io::format is a class template)
> > std::cout << io::set_format<std::vector>(...); // Set generic format for
> > std::vector (io::format overloaded with a version taking template
template
> > parameter, and specialised for std::vector)
>
> Well, <std::vector> would cause trouble because the std::vector requires
> extra arguments... I don't think you could get that to compile.

True, it doesn't, because it's not currently legal C++. :) That's what I
meant with "Overloading of class templates might have helped, here." It's
not possible to overload class templates. However, this is mentioned as a
possible extension, in the "Future Directions" chapter of
Josuttis/Vandevoorde. Together with partial specialisation of function
templates, etc.

> Using
> a string might work... but using it as a template argument would
> probably cause trouble.

Yes, you can't use string literals as template parameters.

> I don't know if there is a way to use partial
> template specialization.

There is, as I showed in the following example. However, it means you have
to provide the parameters to the template, as well (e.g. std::vector), even
if you just mean to set the format for any instantiation of the template.

> There was a recent post about converting type
> names to strings... something like that could be a solution... I don't
> like having to specify a name for each type necessarily though...

Also, as mentioned in the previous posting, it would convert it to a string
of a specific type, which could make it hard to use it as a key for any
instantiation of the template.

Regards,

Terje


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