News:

This week IPhone 15 Pro winner is karn
You can be too a winner! Become the top poster of the week and win valuable prizes.  More details are You are not allowed to view links. Register or Login 

Main Menu

C++ TIps: IO - forward declaring i/o constructs

Started by ben2ong2, October 06, 2006, 11:26:10 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

ben2ong2

(Newsgroups: comp.lang.c++.moderated, 2 Feb 98)

CUTHBERT: You are not allowed to view links. Register or Login (David A. Cuthbert)

> (btw, I'm not completely serious about this.  I do think that writing
> "class ostream;" is comparable to legacy C code (half-ANSI, half-K&R)
> that has "void printf();" in the code rather than
> "#include <stdio.h>".)

AUSTERN: Matt Austern <austern@isolde.mti.sgi.com>

Actually, writing "class ostream" is wrong for two reasons---and I
really do mean wrong; I'm not just giving my opinion about style.

First, it's not ostream but std::ostream.

Second, std::ostream isn't a class at all, but a typedef.  So it's
not enough to just forward-declare ostream; you have to declare the
class that it actually stands for.  A full forward-declaration for
ostream is actually rather tricky; it would look something like this.

namespace std {
  template <class charT> class char_traits;
  template<> class char_traits<char>;
  template <class charT, class traits> class basic_ostream;
  typedef basic_ostream<char, char_traits<char> > ostream;
}

Note that the standard library contains a header, <iosfwd>,
that does exactly this.

---------------------------------------------------------------------

(Newsgroups: comp.lang.c++.moderated, 30 Aug 99)


KALB: Jon Kalb <Kalb@LibertySoft.com>

>I am trying to get the syntax right to forward declare a std::ostream.


NARAN: Siemel B. Naran <sbnaran@uiuc.edu>

You can't forward declare the standard library headers.

One reason is that the compiler is allowed to do special optimizations
trigerred by "#include <iostream>" or "#include <deque>".

Another reason is that the compiler may store pre-compiled versions of
the library files, possibly in the compiler itself.  The a statement
like "#include <deque>" unlocks the pre-compiled version.

A third reason is that the class or function may have additional
default arguments.  Maybe a library implementor has used
   template <class T, class Allocator=allocator<T>, size_t Block=16>
   class vector;
The third template argument is non-standard, but it is reasonable.

Then if you tried this
   // forward declaration
   namespace std { template <class T, class Alloc> class vector; };
your code would compile on most compilers and libraries.  But the
code would not compile on the compiler and library that uses the
third "size_t Block" template argument.



Take a look at <iosfwd> to declare the standard iostreams.
There you'll also learn the proper way to forward declare iostream.
The issue is that std::ostream is a typedef, not a class.

There is no way to forward declare std::deque, etc.

Another option is to declare an implementation in the .hh file and
define it in the .cc file.

// myfile.hh
namespace myspace { class ostream; void Print(ostream); };

// You are not allowed to view links. Register or Login
#include "myfile.hh"
#include <iostream>
struct myspace::ostream
{
   std::ostream& o;
   ostream(std::ostream& o) : o(o) { }
};
void myspace::Print(myspace::ostream strm) { ... };
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login