このクラスははるかに大きいですが、問題のあるコードを投稿します。
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>
次に、特定のメッセージを処理するプライベートメソッドを作成し、AddHandler関数を呼び出して、メッセージIDを渡し、次にそのメソッドへのポインターを渡します。ケーキのように簡単で、マップに正しく入力されていることを確認しました。ただし、BaseWindowクラスでは、次のエラーが発生します。
error C2064: term does not evaluate to a function taking 2 arguments
私がポインタを回すすべての場所で、宣言は確かに2つの引数を取るので、これは奇妙だと思います。かっこと引数を削除して、次のように表示します。
it->second;
コンパイルして実行します。もちろん、どのハンドラーも呼び出されませんが、引数リストを取得せずに2つのパラメーターを持つ関数ポインターが呼び出された場合、どのようにコンパイルできますか?何かが怪しいし、率直に言って私はそれを理解していません。あなたの素晴らしい心の誰かがこれについて何か洞察を持っていますか?