Forward Declarations

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.

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值