質問: test2.hに宣言されている名前空間Bでtest1.hに宣言されている名前空間Aに宣言されたクラスをメンバとしているのですが, 以下のようなエラーが出ます. test1.hでの `#include"test2.h"` を消せば上手く行くのは分かったのですが, なぜ上手く行くのかが分からないです. よろしくお願いします. **エラーメッセージ** ``` test2.h test1.h In file included from test1.h:3:0, from test1.cpp:1, from test3.cpp:2: test2.h:7:5: error: ‘A’ does not name a type A::K t; ^ In file included from test3.cpp:3:0: test2.cpp: In function ‘void B::Func()’: test2.cpp:3:2: error: ‘t’ was not declared in this scope t.k=100; ^ test2.cpp:3:2: note: suggested alternative: ‘tm’ t.k=100; ^ tm In file included from test1.h:3:0: test2.h:7:5: error: ‘A’ does not name a type A::K t; ``` ### ソースコード test1.h ``` #ifndef test1_H_ #define test1_H_ #include #include"test2.h" namespace A{ class K{ public: int k; void main(); }; }; #endif ``` test1.cpp ``` #include"test1.h" void A::K::main(){ std::cout << A::K::k << std::endl; } ``` test2.h ``` #ifndef test2_H_ #define test2_H_ #include #include"test1.h" namespace B{ A::K t; void Func(); }; #endif ``` test2.cpp ``` #include"test2.h" void B::Func(){ t.k=100; t.main(); } ``` test3.cpp ``` #include #include"test1.cpp" #include"test1.h" #include"test2.cpp" #include"test2.h" int main(){ B::Func(); } ```
回答: `test3.cpp`の`#include`の内容を忠実に追えばわかることです。 ``` #include // これは質問と関係ないので追わない #include"test1.cpp" #include"test1.h" #ifndef test1_H_ #define test1_H_ // test1_H_がここで定義される #include // これは質問と関係ないので追わない #include"test2.h" #ifndef test2_H_ #define test2_H_ #include // これは質問と関係ないので追わない #include"test1.h" #ifndef test1_H_ // test1_H_は定義済みなので#endifまで無視される #endif namespace B{ A::K t; // ここより上にAに関する宣言が存在しない void Func(); }; #endif namespace A{ class K{ public: int k; void main(); }; }; #endif void A::K::main(){ std::cout << A::K::k << std::endl; } #include"test1.h" #include"test2.cpp" #include"test2.h" int main(){ B::Func(); } ``` 見て明らかなように、 `A::K t;` に到達した時点で、 `A` に関する宣言・定義いずれもありません。ですのでエラーになります。 というように、`#include`はいい感じに解決してくれる魔法のキーワードというわけではなく、愚直に指定された行に指定されたファイルの内容をインクルードする機能です。 逆に言えば、`#include`結果は開発者にも正確に理解できる機能であり、test3.cppで書かれた ``` #include"test1.cpp" #include"test1.h" #include"test2.cpp" #include"test2.h"` ``` のように何でもかんでも`#include`すれば問題が解決できるなどと考えるべきではありません。もっとご自身の書いたソースコードに目を向けましょう。