Solution

I l @ ve RuBoard

graphics/bulb.gif

1. Forward declarations are very useful tools. In this case, they don't work as the programmer expected. Why are the marked lines errors?

  // file f.h   //   class ostream;  // error   class string;   // error   string f( const ostream& );  

Alas, you cannot forward-declare ostream and string this way because they are not classes. Both are typedef s of templates.

(True, you used to be able to forward-declare ostream and string this way in pre-standard C++, but that was many years ago. It is no longer possible in the standard language.)

2. Without including any other files, write the correct forward declarations for ostream and string above.

Short answer: This is not possible. In fact, it turns out there exists no standard and portable way to forward-declare ostream without including another file, and there is no standard and portable way to forward-declare string at all.

The reason we can't just forward-declare either of these ourselves is that the standard is explicit that we cannot write our own declarations to namespace std , which is where ostream and string live:

It is undefined for a C++ program to add declarations or definitions to namespace std or namespaces within namespace std unless otherwise specified .

Among other things, this rule is intended to let vendors provide implementations of the standard library that have more template parameters for library templates than the standard requires (suitably defaulted, of course, to remain compatible). Even if we were allowed to forward-declare standard library templates and classes, we couldn't do it portably, because vendors are allowed to extend those declarations differently from implementation to implementation.

The best you can do (which is not a solution to the problem "without including any other files") is the following:

 #include <iosfwd> #include <string> 

The iosfwd header does contain bona fide forward declarations. The string header does not. This is all you can do and still be portable. Fortunately, forward-declaring string and ostream isn't too much of an issue in practice, because they're generally small and widely used. The same is true for most standard headers. However, beware the pitfalls, and don't be tempted to start forward-declaring templates, or anything else, that belongs to namespace std . That's a high and solemn privilege reserved for the compiler and library writers, and them alone.

Guideline

graphics/guideline.gif

Never #include a header when a forward declaration will suffice. Prefer to #include only <iosfwd> when the complete definition of a stream is not needed.


See also Exceptional C++ [Sutter00] Item 26.

I l @ ve RuBoard


More Exceptional C++
More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions
ISBN: 020170434X
EAN: 2147483647
Year: 2001
Pages: 118
Authors: Herb Sutter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net