以这段代码为例:
/*
* foo.h
*
* Created on: Nov 5, 2011
* Author: AutoBotAM
*/
#ifndef FOO_H_
#define FOO_H_
template<typename Type>
class Foo
{
public:
void Bar(Type object);
};
#endif /* FOO_H_ */
.
/*
* foo.cpp
*
* Created on: Nov 5, 2011
* Author: AutoBotAM
*/
#include <iostream>
using namespace std;
#include "foo.h"
template<typename Type>
void Foo<Type>::Bar(Type object)
{
cout << object;
}
.
/*
* main.cpp
*
* Created on: Oct 15, 2011
* Author: AutoBotAM
*/
#include <iostream>
using namespace std;
#include "foo.h"
Foo<int> foo;
int main()
{
cout << "The year is ";
foo.Bar(2011);
return 0;
}
这就是我通常如何声明非模板类。不幸的是,此代码导致错误 ../src/main.cpp:18: undefined reference to 'Foo<int>::Bar(int)'
(在 MinGW 中)。我做了一些阅读,结果发现你必须在同一个翻译单元中声明模板类,如下所示:
/*
* foo.h
*
* Created on: Nov 5, 2011
* Author: AutoBotAM
*/
#ifndef FOO_H_
#define FOO_H_
template<typename Type>
class Foo
{
public:
void Bar(Type object)
{
cout << object;
}
};
#endif /* FOO_H_ */
我的大问题是,您为什么必须这样做?我可以想象这个方案在开发过程中会遇到一些陷阱。例如,假设我们有 50 个翻译单元 #including foo.h
,然后我们对 void Foo::Bar(Type)
进行更改.自 Bar
在头文件中,我们必须等待所有 50 个翻译单元编译后才能得到任何结果。如果我们有 Bar
在 foo.cpp
工作单独地,我们只需要等待 1 个翻译单元编译。有什么方法可以解决这个问题吗?
感谢您的任何建议!
最佳答案
模板位于编译和链接时间之间。在看到模板声明后,急切的实现可以做很多事情,但在使用模板参数实例化模板之前,无法生成实际代码。
您可以在 cpp 文件中包含模板类函数,并且您可以使用将要使用的参数显式实例化它。但是,您只能在整个程序中使用这些实例化。例如,您可以添加到 foo.cpp
template class Foo<int>;
现在您可以使用 Foo<int>
即使实现在其自己的翻译单元中,它也无处不在。但是,您不能使用任何其他类型的 Foo<>
因为链接器将无法找到它的功能(它们实际上并不存在)。
关于c++ - 为什么模板类函数必须在同一个翻译单元中声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8024010/