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

时间:2013-05-28 14:02:04

标签: c++ templates gcc c++11 compilation

标题不代表我的问题,但我找不到正确的标题,随时可以编辑。

背景:

炸弹人学校项目。

在我的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

我真的不明白,请解释为什么无法生成这个模板化函数的可能原因。

告诉我您是否需要更多信息。

1 个答案:

答案 0 :(得分:3)

在C ++中,模板被理解为编译器生成代码的模板。所以编译器必须知道模板的每个实例,实现是什么,即它应该在模板定义的头文件中。

您可以为这样的模板具体实现:

template <typename T>
T f(T) { ...}

template<> 
int f<int>(int) {...} 

然后链接器将找到具体类型的实现,并将首选使用它来编译生成的版本。

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

有两种可能的解决方案:

  1. 您提供默认模板实施,而不仅仅是签名
  2. 您为所请求的类型提供了模板的具体化。请记住,您必须/可以为模板应处理的每种类型执行此操作。