这个类要大得多,但我只会发布有问题的代码。
template<class T>
class BaseWindow : public IWindow
{
typedef void(T::*HandlerPtr)(WPARAM, LPARAM)
public:
LRESULT CALLBACK BaseWindow<T>::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
// various stuff
private:
void AddHandler(long id, HandlerPtr func);
private:
std::map<long, void(T::*)(WPARAM, LPARAM)> m_MessageHandlers;
}
template<class T>
void BaseWindow<T>::AddHandler(long id, HandlerPtr func)
{
m_MessageHandler.insert(std::pair<long, HandlerPtr>(id, func));
}
template<class T>
LRESULT CALLBACK Dapper32::BaseWindow<T>::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if(m_MessageHandlers.count(msg) == 1)
{
auto it = m_MessageHandlers.find(msg);
it->second(wparam, lparam); // <-- error here for all template instantiations
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
这里有一点背景。为了好玩和练习,我正在制作一个 win32 包装器,因为它看起来是一个有趣、冗长的项目来解决。经过一番深思熟虑,我决定我更喜欢将消息处理程序存储在映射中的系统,而不是每条消息都到达自己的虚拟函数,或者更糟糕的是,使用巨大的 switch 语句。这里的目标是,您从这个 BaseWindow 类派生,然后模板参数就是该派生类。就像是
class MyWindow : public BaseWindow<MyWindow>
然后您创建将处理特定消息的私有方法,然后调用传递消息 id 的 AddHandler 函数,然后是指向该方法的指针。像蛋糕一样简单,我已经验证它们已正确输入到地图中。但是,在 BaseWindow 类中,我收到错误:
error C2064: term does not evaluate to a function taking 2 arguments
我觉得这很奇怪,因为我在指针周围传递的每个地方,声明肯定有两个参数。当我删除括号和争论使其看起来像:
it->second;
它编译并运行,当然,没有调用任何处理程序,但是当调用具有两个参数的函数指针而不使用争论列表时,它怎么能编译呢?有些东西很可疑,坦率地说我不明白。你们有没有聪明的头脑对此有任何见解?