如何在C ++中调用externed模板函数

时间:2012-12-27 12:01:11

标签: c++ templates extern

  

可能重复:
  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)函数。

非常感谢。

3 个答案:

答案 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) { };

但请注意,如果保持正常功能,它仍然是更好的匹配。