【问题标题】:Use a templated function outside of the .cpp file without declaring it in the .hh file在 .cpp 文件之外使用模板化函数,而不在 .hh 文件中声明它
【发布时间】:2013-05-28 14:02:04
【问题描述】:

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

上下文:

学校的炸弹人项目。

在我的Bomberman 中,我有一个execAfter() 函数原型如下:

void execAfter(std::function<void(t_params *)> func, t_params *params, int ms);

这个函数的目的是在ms延迟之后执行func,以params结构作为参数。

示例:投下炸弹,X 毫秒后爆炸

它完美地工作(使用 lambda,正如在上一个 SO 问题中所说的 here)。

问题

现在我想对我的函数进行模板化,以便能够传递不同的函数类型和不同的params 类型。

时间.hh

template<typename T, typename U, typename V>
void execAfter(T func, U params, V ms);

时间.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

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

如果您需要更多信息,请告诉我。

【问题讨论】:

  • 你的功能的实现也包括在内?
  • @很快你想要 execAfter() 函数的代码?
  • 没有。我在谈论它:Why can templates only be implemented in the header file。你知道吗?
  • 是的。应包括模板的实施。请再次阅读上面发布的链接。
  • 没问题。很高兴它有帮助:)

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


【解决方案1】:

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

你可以有这样的模板的具体实现:

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

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

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

您现在拥有的是一个没有实现的模板声明,这意味着链接器将仅搜索具体的实现,并且找不到!

有两种可能的解决方案:

  1. 您提供默认模板实现,而不仅仅是签名
  2. 您为请求的类型提供模板的具体化。请记住,您必须/能够为您的模板适用的每种类型执行此操作。

【讨论】:

  • 嗯,我已经用同样的方式完成了其他模板化的函数,它们完美地工作,你认为这可能是一个例外吗?
  • 也许您只在定义下方的 cpp 文件中使用了其他模板化函数?
  • 有趣,我检查一下,很快就会回来。
  • 好的,这就是问题所在。只有在同一个 .cpp 文件中使用它时,才能按照我的方式进行操作。非常感谢。
猜你喜欢
  • 2021-09-14
  • 2022-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
  • 1970-01-01
相关资源
最近更新 更多