繁体   English   中英

为什么我的模板函数指针出现链接器错误?

[英]Why am I getting a Linker error with template function pointer?

我有一个EventMgr类,该类具有用于注册侦听器的模板功能。 但是,当我注册一个侦听器时,链接器给我一个“ 错误LNK2019:无法解析的外部符号 ”。

开胃菜代码:

class EventMgr {

 template< class T, class EvenT>
 void RegisterListener(T* listener, int EventType, void (T::*MemFunc)(EvenT*) );
}

SoundMgr(是一个侦听器)尝试注册事件:

SoundMgr::SoundMgr(void)
{
  EventManager::GetInstance()->RegisterListener(this, 1, (&SoundMgr::handleBulletFired));
}

我不确定为什么它不会链接。 为什么找不到引用类型?

如果仅在.h文件中声明模板,而在.cpp文件中声明实现,则将出现此错误,因为C ++编译器一次只工作一个编译单元。 当编译器找到调用刚刚声明的模板函数的代码时,它将假定具体实例化将由其他某个编译单元完成(编译器无法知道在哪里可以找到该函数的.cpp文件。 ..编译器一次只能看到一个.cpp和所有包含的.h)。

如果模板参数来自一个众所周知的列表,您可以简单地请求所有您知道的.cpp中程序所需的显式实现。

例如,如果您具有模板功能

template<typename T>
T foo(T x)
{
   ...
}

而且您知道只需要int foo(int); string foo(string); 那么就可以只使用.h中的声明,只要您还在.cpp中添加两行即可:

template<> int foo(int);
template<> string foo(string);

这样,您就告诉编译器要构建什么专业。 如果以后您最终使用其他专业化名称(例如, vector<int> foo(vector<int>) ),则还必须在模板的.cpp文件中添加此显式实例化。

但是,在查看代码的示例中,我想您可能事先不知道将定义哪种事件,因此无法执行此显式实例化。

另一种解决方案是将整个模板实现简单地放在.h文件中,而不是将声明与实现分开。 有时这并非易事,因为需要您公开更多的实现细节,可能会引入更多的依赖关系。

这可能意味着RegisterListener实际上并没有在任何地方实现。 由于它是模板函数,因此应在标头中实现它。

尝试在标题中执行以下操作。

template< class T, class EvenT > 
void RegisterListener(T* listener, int EventType, void (T::MemFunc)(EvenT) ) { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM