在.cpp文件之外使用模板化函数,而不必在.hh文件中声明它

Use a templated function outside of the .cpp file without declaring it in the .hh file

本文关键字:文件 不必 声明 函数 hh cpp      更新时间:2023-10-16

标题不能代表我的问题,但我找不到正确的标题,请随意编辑

背景:

学校炸弹侠项目。

在我的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) {...} 

则链接器将找到一个具体类型的实现,并优先使用它而不是编译器生成的版本。

你现在拥有的是一个没有实现的模板声明,这意味着链接器将只搜索具体的实现,而没有找到一个!

有两个可能的解决方案:

  1. 你提供了一个默认的模板实现,而不是只有签名
  2. 您为所请求的类型提供模板的具体化。请记住,你必须/能够为你的模板应该工作的每个类型做这个。