bra*_*ter 1 c++ templates function-pointers linker-errors
我有一个 EventMgr 类,它有一个模板函数来注册一个监听器。但是,当我注册一个监听器时,链接器给了我一个“错误 LNK2019:未解析的外部符号”。
开胃菜代码:
class EventMgr {
template< class T, class EvenT>
void RegisterListener(T* listener, int EventType, void (T::*MemFunc)(EvenT*) );
}
Run Code Online (Sandbox Code Playgroud)
SoundMgr(它是一个侦听器)尝试注册事件:
SoundMgr::SoundMgr(void)
{
EventManager::GetInstance()->RegisterListener(this, 1, (&SoundMgr::handleBulletFired));
}
Run Code Online (Sandbox Code Playgroud)
我不确定为什么它不会链接。为什么找不到引用类型?
如果您只是在 .h 文件中声明模板,而在 .cpp 文件中实现,那么这就是您将得到的错误,因为 C++ 编译器一次只运行一个编译单元。当编译器发现您的代码调用刚刚声明的模板函数时,它会假设具体实例化将由某个其他编译单元完成(编译器无法知道在哪里可以找到该函数的 .cpp 文件。 .. 编译器一次只能看到一个 .cpp 和所有包含的 .h)。
如果模板参数来自众所周知的列表,您可以简单地请求 .cpp 中程序所需的所有显式实现。
例如,如果您有一个模板函数
template<typename T>
T foo(T x)
{
...
}
Run Code Online (Sandbox Code Playgroud)
并且您知道只是需要int foo(int);,string foo(string);然后可以仅使用 .h 中的声明,前提是您还在 .cpp 中添加了两行内容:
template<> int foo(int);
template<> string foo(string);
Run Code Online (Sandbox Code Playgroud)
通过这样做,您是在告诉编译器要构建什么专业化。如果您后来最终使用其他专业化(例如vector<int> foo(vector<int>)),那么您还必须在模板的 .cpp 文件中添加此显式实例化。
但是,在您查看代码的示例中,我猜您事先不知道将定义哪种事件,因此无法完成此显式实例化。
另一种解决方案是简单地将整个模板实现放在 .h 文件中,而不是将声明与实现分开。这有时可能不是微不足道的,因为需要您公开更多实现细节,这可能会引入更多依赖项。
| 归档时间: |
|
| 查看次数: |
2488 次 |
| 最近记录: |