8

テンプレート クラスの周りにガードを含めることは賢明ですか?

テンプレート クラスは、異なる実装で参照するたびに再解析されるはずではありませんか?

NB Visual C++ 2008 では、この 2 つを組み合わせてもエラーは発生しません...

4

4 に答える 4

13

ガードを含める必要があります。次のコードを検討してください。

// 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

また、テンプレートを含むヘッダーには、通常、テンプレート以外のコードも含まれています。

于 2010-03-08T12:35:43.360 に答える
8

テンプレートの定義は 1 回解析されることになっています (そして、インスタンス化せずにできるだけ多くのエラーをすぐに与えることができるように、2 つのフェーズの名前検索のようなものがここにあります)。インスタンス化は、その時点で構築された内部データ構造を使用して行われます。

テンプレート定義は通常 (つまり、export何か特別なことを使用または実行していない場合)、インクルード ガードが必要なヘッダー ファイルにあります。テンプレート定義用に 1 つ追加しても無駄ですが、害はありません。

于 2010-03-08T12:32:41.867 に答える
2

最初の質問に答えるには: はい、テンプレート クラスの周りにガードを含めることは賢明であり、必須です。または、すべてのヘッダー ファイルの内容全体をより厳密に囲みます。

これは、ヘッダー ファイルに何かがある場合に One Definition Rule に従う方法であり、共有されていても安全です。あなたのものを含む他のヘッダーファイルがあるかもしれません。コンパイラがモジュール ファイルをコンパイルするとき、#includeヘッダー ファイルの が何度も表示される場合がありますが、2 回目以降はガードが作動して、コンパイラが内容を 1 回だけ確認するようにします。

コンパイラが何かを再解析することは問題ではありません。それがその仕事です。コンテンツを 1 回提供するだけで、コンパイラーはそれを認識し、必要に応じて何度でも参照できます。

于 2010-03-08T13:33:48.853 に答える
2

簡単な答え: 定義に複数回含める予定のすべてのユニットには、ヘッダー ガードが必要です。それは、テンプレートの有無にかかわらずです。

于 2010-03-08T13:17:11.467 に答える