为什么我的模板函数指针出现链接器错误? [英] Why am I getting a Linker error with template function pointer?

查看:87
本文介绍了为什么我的模板函数指针出现链接器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class EventMgr which has a template function to register a listener. But, when I register a listener, linker gives me a "error LNK2019: unresolved external symbol".

开胃菜代码:

class EventMgr {

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

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

SoundMgr(which is a listener) tries to register for event:

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

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

I'm not sure why it won't link. Why can it not find the reference types ?

推荐答案

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

If you simply declared the template in a .h file and the implementation is instead in a .cpp file then this is the error you will get, because a C++ compiler works one compile unit at a time. When the compiler finds your code calling a template function that has been just declared it will assume that the concrete instantiation will be done by some other compilation unit (there is no way the compiler can know where to find the .cpp file for that function... the compiler only sees one .cpp and all the included .h at a time).

如果模板参数来自一个众所周知的列表,则只需在.cpp中请求所需的所有显式实现即可.

If the template parameters are from a well known list you can simply request the all explicit implementations you know that will be needed for the program in the .cpp.

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

For example if you have a template function

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

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

and you know are just going to need int foo(int); and string foo(string); then it's fine to use just the declaration in the .h, provided you also add two lines in the .cpp saying:

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

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

By doing that you are telling the compiler about what specialization to build. If you later end up using other specializations (e.g. vector<int> foo(vector<int>)) then you must also add this explicit instantiation in the .cpp file of the template.

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

However in your example looking at the code I guess that you don't know in advance which kind of events will be defined and so this explicit instantiation cannot be done.

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

The other solution is to simply put the whole template implementation in the .h file instead of separating declaration from implementation. This sometimes can be not trivial because requires you to expose more implementation details probably introducing more dependencies.

这篇关于为什么我的模板函数指针出现链接器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆