首先。编译器仅在实例化模板时生成代码(在您的示例中,由于没有实例化,因此不生成代码)。其次,你传递一个类型模板参数。这里编译器将被允许安全地创建一个实例。 在你的例子中,你不会在某处使用这个类型,但是如果你愿意,为了定义一个函数,我的第一句话将再次适用,并且该函数只是在某个地方实例化时生成的。 就在这时,编译器必须具备所有知识才能生成代码。
// 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
@Quentin:谢谢你的回答。如果此代码是库的一部分,那么模板 :: someFunc()符号将在lib中导出,并且在定义A时不会导致未解析的外部错误? – Michel