这个类要大得多,但我只会发布有问题的代码。
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>
然后您创建将处理特定消息的私有(private)方法,然后调用传入消息 ID 的 AddHandler 函数,然后是指向该方法的指针。简单易行,我已验证它们已正确输入 map 。但是,在 BaseWindow 类中,出现错误:
error C2064: term does not evaluate to a function taking 2 arguments
我觉得这很奇怪,因为我绕着指针传递的每个地方,声明确实有两个参数。当我删除括号和参数使其看起来像:
it->second;
它编译并运行,当然,没有调用任何处理程序,但是当调用带有两个参数的函数指针而不采用参数列表时,它怎么能编译呢?有些东西很可疑,坦率地说我不明白。你们中的任何聪明人对此有任何见解吗?
最佳答案
你需要这样做:
(it->second)(wparam, lparam); // note parens
关于c++ - 方法指针映射,编译器说它们不接受任何参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13421778/