可能重复:
Why can templates only be implemented in the header file?
我在函数main中编写了一个模板函数和int类型的调用:
template <class T> T max (T a, T b) { }
int main() {
max(1,2);
}
正如大多数C ++书籍所述,当编译器遇到int max(int,int)
时,max(1,2)
函数将在编译期间生成。
但是在另一个文件中,我编写了int max(int,int)
的声明并调用它,但是编译器(实际上是链接器)发现错误,表示找不到max(int,int)
的引用。
extern int max(int,int);
max(1,2); // Error:undefined reference to max(int,int)
那么,错误点是什么,如何使用extern而不是头文件声明来调用max(int,int)函数。
非常感谢。
答案 0 :(得分:2)
这个问题只回答了几千次。简短形式是:您必须安排模板定义在使用时可见,以便编译器可以隐式实例化函数模板,或者您必须显式实例化函数模板。
注意,声明extern int max(int, int);
声明了一个非模板函数max()
,它将两个int
作为参数。无论是否实例化,函数模板都不会满足此引用。
答案 1 :(得分:1)
extern int max(int,int);
声明了非模板函数。它与模板不匹配,即使在您的其他文件中可见。
正确的方法是将模板放在标题中,并在使用函数的任何地方包含它(或者更好的是,使用标准库中已有的max
模板)。
答案 2 :(得分:0)
当你声明extern int max(int, int)
时,你告诉编译器有一个函数在某处定义了这个签名,不一定在同一个翻译单元中。 extern
实际上是多余的,因为默认情况下函数具有外部链接。
现在,您似乎认为此声明提供了模板函数实例化的定义,其中T = int。它没有,两者没有任何关联。当编译器搜索呼叫max(1,2)
的候选者时,普通函数优先于函数模板。当它找到声明int max(int, int)
时,它是一个完美的匹配并且它的工作已经完成 - 它甚至从未尝试实例化模板。编译完成后,链接器应该找到定义,并且你没有提供它,你得到一个未定义的引用。
所以你可以写一个定义
int max(int, int) { }
或明确告诉编译器使用模板
max<int>(1,2);
您还可以专门化 int
类型
template<>
int max<int>(int, int) { };
但请注意,如果保持正常功能,它仍然是更好的匹配。