2012-04-10 6 views
1

私はmy_program.cppとそのヘッダmy_program.hの2つのファイルを持っています。次のようにiostreamとwstringを含む奇妙なC++の動作

#include "my_program.h" 
using namespace std; 

my_program.hは、wstringを返す関数へのポインタを含む:

using namespace std; 
typedef wstring (*my_function)(wstring, int, int, int, int); 

プログラム(この状態ではコンパイルされない

my_program.cppのみこれを含んtypedefで止まります... ISO C++は型なしの 'wstring'の宣言を禁じていますが)#include "my_program.h"の前に#include <iostream>を追加すると.cppプログラムは、奇跡的にコンパイルします。

どうしてですか?私は愚かな間違いをしなかったことを願っています。そして、今私は笑われるつもりです。

+0

このtypedef宣言を完全に読むことはできませんが、そのtypedefの新しい型名はどこですか? – Frizi

+1

'#_include 'を 'my_porgram.h'に入れましたか? – scientiaesthete

+1

@Frizi 'my_function'はtypedefの名前です。 wstringを返し、wstring、int、int ...をパラメータとして持つ関数へのポインタです。 –

答えて

5

実際には<string>を含める必要があります。

コンパイラの<iostream>には<string>が含まれているので、動作しますが、別のコンパイラではそうではありません。 C++では、標準ヘッダに他の標準ヘッダを含めることができますが、それを必要としません。場合によっては、クラスの宣言しか得られないため、いくつかのものが動作し、他のものは動作しません。

少なくとも私の経験では、これはコンパイラのあるバージョンから次のバージョンに変更される可能性がある問題であるため、他のものに移植するつもりがない場合でも、コードが間に合って動作しなくなることがありますあなたが正しいヘッダーを含まない限り、一見些細なアップグレードに。

+0

私の悪い。私はそれを知っていたはずです。どうもありがとうございました。 –

0

あなたが#include <iostream>を追加する前に、コンパイラはwstringが何であるかわかりません - それ故にエラー

あなたは(std::wstringを定義する - おそらくそれは含まれて他のヘッダ経由)のiostreamヘッダーを含めるした後、コンパイラは知っていますwstringは、typedefを参照し、正しく解析できます。

コンパイラは、ヘッダーではなく、コンパイル単位(.cppファイル)と呼ばれるものだけを気にします。ヘッダーは、コンパイル単位にそれらが含まれているときに機能します(コピーとペーストをそのまま使用します)。したがって、typedefの前の任意の場所にあるiostream(または他のものが<string>と指摘されています)を含めることができます。ヘッダーの最初の行にヘッダーを含める前と同じように、この観点からも機能します。

しかし、ヘッダーを可能な限り一貫性のあるものにすることは、一般的には良い考えです(したがって、.cppではなくヘッダーに関連するヘッダーを含めることをお勧めします)。意図したとおりに動作させるために、他のヘッダもインクルードしてください。

+0

私は 'using namespace std;'を '#include" my_program.h "'の前にcppで移動しました。 –

+0

「それは同じですが」とはどういう意味か分かりませんが、 'using namespace std;'宣言は 'std'名前空間のすべてをグローバル名前空間に"持ち上げる "ので、すべてに' std'を付ける必要はありません( 'std :: wstring'の代わりに' wstring'のように)、 'include 'の後で 'typedefの前にある限り、このケースでは.cppやヘッダに違いはありません' – Attila