iostream よりも iosfwd を #include して、余分なコンパイルを抑制する2019年03月25日 14時16分53秒

C++ 言語の一般的な、入出力ストリームは iostream ファイルに記述されている。cin や cout 等が使えるようになる。

最初のうちはこれでも良いのだが、C++ コードも大きくなり、独自のクラスの数も増えてくると、コンパイルにかかる時間が延びてくる。クラスを書くと、自ずとその入出力関数が必要になってくる。特に、cout での表示はデバッグなども含めて必須になってくる。

実は、iosfwd が cin や cout 等の前方宣言を行っている。テンプレートクラスでも書かない限り、コンパイラが自前クラスのヘッダファイル内で必要なのは、io クラスの前方宣言だけであり、コンパイラにそれらのクラスが存在することを伝えるだけで良い。iostream は入出力の実装が含まれているので、それをヘッダファイルで読み込んでしまうと、コンパイラが全てのファイルで iostream 関数が実装することになり、コンパイルの時間が増えてしまう。酷いときになると、コンパイラがメモリ不足に陥って、コンパイルに失敗する。

簡単な例を上げよう。

% cat uyota.h
#include <iostream>

class uyota
{
    friend std::ostream& operator<<( std::ostream& out, const uyota& self );
};
このクラスの、ostream 演算子は、cpp で実装されているので、コンパイラが知る必要があるのは std::ostream クラスがあり、各種演算子が存在することだけで事足りる。
% cat uyota.h
#include <iofwd>

class uyota
{
    int age_;
    friend std::ostream& operator<<( std::ostream& out, const uyota& self );
};
そのため、ioswfd にしても、問題なくコンパイルできるし、コンパイルの速度も早くなり、メモリの利用量も減る。