From -3108285791119065016
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 109fba,d79034ba38bfd51a
X-Google-Attributes: gid109fba,public
X-Google-Thread: f78e5,d79034ba38bfd51a
X-Google-Attributes: gidf78e5,public
From: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Subject: Re: ANSI ostringstream breaks idiom
Date: 1997/09/29
Message-ID: <342FE3F5.4E7E3DB0@physik.tu-muenchen.de>#1/1
X-Deja-AN: 276492058
References: <dent-ya023480002209970647180001@news.highway1.com.au> <m3hgbaylas.fsf@gabi-soft.fr>
X-Original-Date: Mon, 29 Sep 1997 19:23:01 +0200
Organization: [posted via] Leibniz-Rechenzentrum, Muenchen (Germany)
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUANC/0EOEDnX0m9pzZAQEH0wF/UWh72qGKOAA7yV3Qup/y5WpOmWXnDaUb JVgiG7r8B6t4xl6sodcZgMRLiSy/deHL =yHNZ
Newsgroups: comp.std.c++,comp.lang.c++


J. Kanze wrote:

[...]

> The temporary is not the problem here.  In the above line, what you are
> passing is the return value of the last operator<<.  All operator<<'s
> return an ostream&.  This is, by definition, an lvalue, and so can bind
> to your reference.  But it is NOT an ostringstream -- it is an ostream.
> (For type checking purposes, of course.  Its dynamic type is still
> ostringstream, and any virtual functions, like the destructor, will
> still act on the ostringstream.
> 
> Although somewhat a pain, in this case, the only solution I've found is
> to declare the function to take an ostream&, and dynamic_cast it back up
> to the desired stream type in the function.  Of course, this means that
> any errors will only be caught at runtime (in the dynamic_cast), and not
> at compile time.

What about the following solution:

#include <iostream.h>
#include <strstream.h>

template<class OSTREAM> class ostream_wrapper
{
  OSTREAM& os;
public:
  ostream_wrapper(OSTREAM& ost): os(ost) {}
  operator OSTREAM&() { return os; }
  ostream_wrapper& lvalue() { return *this; }
};

template<class OSTREAM, class T> inline
 ostream_wrapper<OSTREAM>& operator<<(ostream_wrapper<OSTREAM>& o, const
T& t)
{
  ostream& oo(o);
  oo << t;
  return o;
}

template<class OSTREAM> inline
 ostream_wrapper<OSTREAM>& operator<<(ostream_wrapper<OSTREAM>& o,
                                      ostream&(*f)(ostream&))
{
  ostream& oo(o);
  oo << f;
  return o;
}

template<class OSTREAM> ostream_wrapper<OSTREAM> wrapos(OSTREAM& o)
{
  return o;
}

void f(ostrstream& ost)
{
  cout << ost.str() << endl;
  ost.freeze(0);
}

int main()
{
  ostrstream s;
  f(wrapos(s).lvalue() << "Testing the wrapper..." << ends);
  return 0;
}

This should be compile-time typesafe, and should have less overhead than
dynamic_cast (a good optimizer might even reduce it to zero).
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]



