在.cpp文件之外使用模板化函数,而不必在.hh文件中声明它
Use a templated function outside of the .cpp file without declaring it in the .hh file
标题不能代表我的问题,但我找不到正确的标题,请随意编辑
背景:
学校炸弹侠项目。
在我的Bomberman
中,我有一个execAfter()
函数原型如下:
void execAfter(std::function<void(t_params *)> func, t_params *params, int ms);
此函数的目的是以params
结构体为参数,在ms
延迟后执行func
。
示例:投下炸弹,X毫秒后爆炸
它可以完美地工作(在前面的SO问题中使用lambda)。
问题现在我想模板我的函数,以便能够传递不同的函数类型和不同的params
类型。
Time.hh
template<typename T, typename U, typename V>
void execAfter(T func, U params, V ms);
Time.cpp
template<typename T, typename U, typename V>
void Time::execAfter(T func, U params, V ms)
{
...
}
(模板V
参数是无用的,但它只是为编译问题,我将找出如何做稍后)
示例:*调用函数void X(Y)
,传递参数Y*
。
我做的一切都是正确的,从我的角度来看,一切都编译,除了链接之后gcc抛出这个:
[...]
linkage ...
[...]
src/Entities/Character.o: In function `Character::landBomb()':
/home/teube_a/Code/tech2/c++/bomberman-2016- couille_c/zizi_g/src/Entities/Character.cpp:208: undefined reference to `void Time::execAfter<std::function<void (s_params*)>, s_params*, int>(std::function<void (s_params*)>, s_params*, int)'
collect2: ld returned 1 exit status
make: *** [bomberman] Error 1
我真的不明白,请解释一下为什么这个模板函数不能生成。
如果你需要更多的信息就告诉我。
在c++中,模板被理解为编译器生成代码的模板。所以编译器必须知道在模板的每一个实例化,实现是什么,也就是说,它应该在头文件中模板被定义。
你可以有这样的模板的具体实现:
template <typename T>
T f(T) { ...}
template<>
int f<int>(int) {...}
则链接器将找到一个具体类型的实现,并优先使用它而不是编译器生成的版本。
你现在拥有的是一个没有实现的模板声明,这意味着链接器将只搜索具体的实现,而没有找到一个!
有两个可能的解决方案:
- 你提供了一个默认的模板实现,而不是只有签名
- 您为所请求的类型提供模板的具体化。请记住,你必须/能够为你的模板应该工作的每个类型做这个。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- 将内存保存到文件并加载它而不必解析数据?
- 如何在源文件中定义类并将其声明在标题文件中(而不必使用`class :: method'语法定义类方法)
- 如何默认包含某些头文件,这样我就不必在每个程序中键入它们
- G++ 为什么你不必链接 iostream 二进制文件,但对于 pthread,你这样做了?
- 在.cpp文件之外使用模板化函数,而不必在.hh文件中声明它
- 如何打开一个文件而不必输入整个文件路径
- 如何编译c++文件的一个子集,使我不必编译其他文件MinGW