テンプレートの仕組みに関する本を読んでいるのですが、テンプレートの説明が理解しにくいです。
それは言う
コンパイラはテンプレートの定義を見ると、コードを生成する. テンプレートの特定のインスタンスをインスタンス化するときにのみコードが生成されます。テンプレートを使用するときにのみコードが生成され (定義するときには生成されない)、ソース コードの編成方法やエラーが検出されるタイミングに影響します...インスタンス化を生成するには、コンパイラに関数テンプレートまたはクラス テンプレート メンバー関数を定義するコードが必要です。その結果、非テンプレート コードとは異なり、テンプレートのヘッダーには通常、定義と宣言が含まれます。
「コードを生成する」とは、具体的にはどういう意味ですか? 関数テンプレートまたはクラス テンプレートをコンパイルする場合と、通常の関数またはクラスをコンパイルする場合の違いがわかりません。
ベストアンサー1
コンパイラ生成するテンプレート クラスのインスタンス化で指定された特定の型のコード。
例えば、次のようなテンプレートクラス宣言があったとします。
template<typename T>
class Foo
{
public:
T& bar()
{
return subject;
}
private:
T subject;
};
たとえば、次のようなインスタンスを作成すると、
Foo<int> fooInt;
Foo<double> fooDouble;
これらは効果的に生成する次のようにクラスを定義した場合と同じリンク可能なコード
class FooInt
{
public:
int& bar()
{
return subject;
}
private:
int subject;
}
そして
class FooDouble
{
public:
double& bar()
{
return subject;
}
private:
double subject;
}
そして変数を次のようにインスタンス化する
FooInt fooInt;
FooDouble fooDouble;
テンプレートの点に関して定義(混同しないように宣言テンプレートに関係なく、ヘッダーファイル(インクルードファイル)で確認する必要がある理由は明らかです。
コンパイラは、意味ただし、リンク段階で最初に出現した一致するインスタンス化を参照することもできます。
テンプレート関数にはない、ヘッダーの外部で定義できる非テンプレート メンバー関数には何がありますか?
非テンプレートクラス/メンバー/関数の宣言は、リンカーに定義済みのエントリポイントを提供します。定義は、コンパイルされたオブジェクトファイル(== .cpp ==)にある単一の実装から引き出すことができます。コンパイル単位)。
対照的に、テンプレート化されたクラス/メンバー/関数の宣言は、同じまたは異なるテンプレート パラメータが与えられた任意のコンパイル単位からインスタンス化される可能性があります。これらのテンプレート パラメータの定義は、少なくとも 1 回は確認する必要があります。これは、汎用または特殊化のいずれかになります。
いずれにしても、テンプレート実装を特定の型に特化することができることに注意してください(ヘッダーに含まれるか、特定のコンパイル単位)。テンプレートクラスに特殊化を提供する場合は、コンパイル単位、テンプレート クラスを特殊化された型以外で使用しないでください。これもすべてをリンクするのに十分です。
このサンプルが、コンパイラの違いと行われた作業を明確にするのに役立つことを願っています。