Forward declarations are a great way to eliminate needless compile-time dependencies. But here's an example of a forward-declaration snare... how would you avoid it?
![]()
Problem
JG Question
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
#ifndef XXX_F_H_
#define XXX_F_H_
class ostream; // error
class string; // error
string f( const ostream& );
#endif
Guru Question
2. Without including any other files, can you write the correct forward declarations for ostream and string above?
![]()
Solution
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
#ifndef XXX_F_H_
#define XXX_F_H_
class ostream; // error
class string; // error
string f( const ostream& );
#endif
Alas, you cannot forward-declare ostream and string this way because they are not classes... both are typedefs of templates.
(True, you used to be able to forward-declare ostream and string this way, but that was many years ago and is no longer possible in Standard C++.)
2. Without including any other files, can you write the correct forward declarations for ostream and string above?
Unfortunately, the answer is that there is no standard and portable way to do this. The standard says:
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 allows vendors to 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).
The best you can do (which is not a solution to the problem "without including any other files") is this:
#include <iosfwd>
#include <string>
The iosfwd header does contain bona fide forward declarations. The string header does not. This is all that you can do and still be portable. Fortunately, forward-declaring string and ostream isn't too much of an issue in practice since 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 reserved for the compiler and library writers, and them alone.
本文探讨了在C++中对于标准库类型如ostream和string进行前向声明时遇到的问题,并解释了为什么这种做法会导致错误。此外,文章还讨论了如何正确地为这些类型做前向声明的方法。
788

被折叠的 条评论
为什么被折叠?



