标题不代表我的问题,但我找不到正确的标题,随时可以编辑。
炸弹人学校项目。
在我的Bomberman
我有execAfter()
函数原型如下:
void execAfter(std::function<void(t_params *)> func, t_params *params, int ms);
此函数的目的是执行func
,在params
延迟后将ms
struct作为参数。
示例:放下炸弹,在X ms后展开。
它完美地运行(在之前的SO问题上使用lambda告诉here)。
现在我想模拟我的函数,以便能够传递不同的函数类型和不同的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
param是没用的,但它只是出于编译问题,我会想出以后怎么办)
示例:*调用函数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
我真的不明白,请解释为什么无法生成这个模板化函数的可能原因。
告诉我您是否需要更多信息。
答案 0 :(得分:3)
在C ++中,模板被理解为编译器生成代码的模板。所以编译器必须知道模板的每个实例,实现是什么,即它应该在模板定义的头文件中。
您可以为这样的模板具体实现:
template <typename T>
T f(T) { ...}
template<>
int f<int>(int) {...}
然后链接器将找到具体类型的实现,并将首选使用它来编译生成的版本。
你现在拥有的是一个没有实现的模板声明,这意味着链接器只会搜索具体的实现,而不会找到一个!
有两种可能的解决方案: