1

可能重复:
为什么模板只能在头文件中实现?

我在函数 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) 函数。

非常感谢。

4

3 回答 3

2

这个问题只回答了几千次。简短的形式是:您必须安排模板定义在使用时可见,以便编译器可以隐式实例化函数模板,或者您必须显式实例化函数模板。

请注意,该声明声明了一个以两个作为参数extern int max(int, int);的非模板函数。函数模板永远不会满足这个引用,无论它是否被实例化。max()int

于 2012-12-27T12:04:03.050 回答
1

extern int max(int,int);声明一个非模板函数。它与模板不匹配,即使该模板已在您的其他文件中可见。

正确的方法是将模板放在头文件中,并在使用该函数的任何地方都包含该模板(或者,甚至更好的是,使用max标准库中已有的模板)。

于 2012-12-27T12:12:26.203 回答
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) { };

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

于 2012-12-27T12:29:24.203 回答