テンプレート クラスの周りにガードを含めることは賢明ですか?
テンプレート クラスは、異なる実装で参照するたびに再解析されるはずではありませんか?
NB Visual C++ 2008 では、この 2 つを組み合わせてもエラーは発生しません...
テンプレート クラスの周りにガードを含めることは賢明ですか?
テンプレート クラスは、異なる実装で参照するたびに再解析されるはずではありませんか?
NB Visual C++ 2008 では、この 2 つを組み合わせてもエラーは発生しません...
ガードを含める必要があります。次のコードを検討してください。
// this is t.h
template <typename T>
void f( T t ) {
}
// this is t.cpp
#include "t.h"
#include "t.h"
int main() {
f( 1 );
}
これにより、次のエラーが発生します。
t.h:2: error: redefinition of 'template<class T> void f(T)'
t.h:2: error: 'template<class T> void f(T)' previously declared here
また、テンプレートを含むヘッダーには、通常、テンプレート以外のコードも含まれています。
テンプレートの定義は 1 回解析されることになっています (そして、インスタンス化せずにできるだけ多くのエラーをすぐに与えることができるように、2 つのフェーズの名前検索のようなものがここにあります)。インスタンス化は、その時点で構築された内部データ構造を使用して行われます。
テンプレート定義は通常 (つまり、export
何か特別なことを使用または実行していない場合)、インクルード ガードが必要なヘッダー ファイルにあります。テンプレート定義用に 1 つ追加しても無駄ですが、害はありません。
最初の質問に答えるには: はい、テンプレート クラスの周りにガードを含めることは賢明であり、必須です。または、すべてのヘッダー ファイルの内容全体をより厳密に囲みます。
これは、ヘッダー ファイルに何かがある場合に One Definition Rule に従う方法であり、共有されていても安全です。あなたのものを含む他のヘッダーファイルがあるかもしれません。コンパイラがモジュール ファイルをコンパイルするとき、#include
ヘッダー ファイルの が何度も表示される場合がありますが、2 回目以降はガードが作動して、コンパイラが内容を 1 回だけ確認するようにします。
コンパイラが何かを再解析することは問題ではありません。それがその仕事です。コンテンツを 1 回提供するだけで、コンパイラーはそれを認識し、必要に応じて何度でも参照できます。
簡単な答え: 定義に複数回含める予定のすべてのユニットには、ヘッダー ガードが必要です。それは、テンプレートの有無にかかわらずです。