まずは、コンパイラは、テンプレートがインスタンス化されている場合にのみコードを生成します(インスタンス化がないためコードは生成されません)。次に、型テンプレート引数を渡します。ここで、コンパイラはインスタンスを安全に作成することができます。 あなたの例では、あなたはどこかの型を使用しません。関数を定義するために、私の最初の文が再度適用され、関数はインスタンス化の際にちょうどどこかで生成されます。 この時点で、コンパイラはコードを生成するためのすべての知識を持っていなければなりません。
// Example program
#include <iostream>
template <typename T> struct Template
{
void someFunc(); //defined in the .cpp file
};
class A;
Template<A> foo;
ただし、非型パラメータを使用してテンプレートを作成すると、あなたが懸念しているように、型定義が不完全であるために失敗します。
// Example program
#include <iostream>
#include <string>
class A;
template <A parm> struct Template
{
void someFunc() {
parm.foo();
}
};
A a;
using foo = Template<a>;
この例でも同じです。ここでは、オブジェクトa
を作成します。もちろん、コンパイラは型の詳細を知る必要があります。これが失敗する理由です。
// Example program
#include <iostream>
template <typename T> struct Template
{
T a;
};
class A;
Template<A> foo;
希望します。
テンプレートを分割して、すべてをヘッダファイルに定義しないでください。 – NathanOliver
ここでは完全にする必要がある「A」の使用はないので、とにかく問題はありません。 – Quentin
@クエンティン:あなたの答えをありがとう。このコードがライブラリの一部である場合、テンプレート :: someFunc()のシンボルはlibにエクスポートされ、Aが定義されているときには未解決の外部は発生しません。 – Michel