17

コンセプトとエラーを理解しようとしています。これの何が問題になっていますか?

class A
{
public:
    A()
    {
        std::function<void(int)> testFunc(&A::func);
    }

private:
    void func(int) {}
}

私の質問ですが、std :: functionがメンバー関数ポインターのように機能する特定のインスタンスのメンバーを呼び出すことができる任意の種類のオブジェクトを作成することは可能ですか?ただし、関数パラメーターとして使用できない奇抜な型定義がない場合を除きますクラスの継承で。例えば:

class A
{
public:
    A()
    {
         index[WM_CREATE] = &A::close;
         index[WM_DESTROY] = &A::destroy;
    }

protected:
    map<UINT msg, void (A::*)(HWND, UINT , WPARAM, LPARAM)> index;
    void close(HWND,UINT, WPARAM, LPARAM);
    void destroy(HWND, UINT, WPARAM, LPARAM);
};

class B : public A
{
public:
    B()
    {
        index[WM_CREATE] = &B::create; // error because it's not a pointer of type A::*
    }
private:
    void create(HWND, UINT, WPARAM, LPARAM);

};

私は次のようなstd::関数を使用する正しい軌道に乗っていると思っています:

class A
{
public:             //         Gigantic stl error with these two
    A()             //                         |
    {               //                         V
         index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::close);
         index[WM_DESTROY] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::destroy);
    }

protected:
    map<UINT msg, std::function<void(HWND, UINT, WPARAM, LPARAM)> > index;
    void close(HWND,UINT, WPARAM, LPARAM);
    void destroy(HWND, UINT, WPARAM, LPARAM);
};

class B : public A
{
public:                    //               and this one
    B()                    //                     |
    {                      //                     V
        index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM)>(&B::create);
    }
private:
    void create(HWND, UINT, WPARAM, LPARAM);

};

誰かがこれらの巨大な不可解なエラーが何を意味するのか、そしてそれらを修正する方法を説明できれば、私はそれを大いに感謝します。

4

3 に答える 3

18

あなたが抱えている問題は、メンバー関数が関数ポインターだけでなく、呼び出し元オブジェクトへのポインターを必要とすることだと思います。つまり、メンバー関数には、呼び出し元オブジェクトへのポインターである追加の暗黙の引数があります。

メンバー関数をstd::functionに設定するには、次のようにstd::bindを使用する必要があります。

std::function<void(int)> testFunc(std::bind(&A::func, this, _1));

これにより、現在のAインスタンスのthisポインターが関数にバインドされ、関数ポインターとオブジェクトインスタンスが作成されます。これは、関数を適切に呼び出すのに十分な情報です。_1引数は、関数が呼び出されたときに最初の明示的な引数が提供されることを示します。

于 2012-04-05T05:18:06.573 に答える
2

c ++ 11では、ラムダを使用することもできます。ラムダは、以下よりも少し読みやすくなっていますstd::bind

index[WM_CREATE] = [this](HWND h, UINT u, WPARAM w, LPARAM l)
{
  create(h, u, w, l);
}
于 2019-08-16T07:27:56.373 に答える
1

私の質問ですが、特定のインスタンスのメンバーを呼び出すことができる任意の種類のオブジェクトを作成することは可能ですか?

この場合、欠落している唯一の情報は、実際には、std::functionオブジェクトが使用する必要がある特定のインスタンスです。&A::funcそれ自体では使用できません(たとえば、instanceで(this->*&A::func)(0)使用&A::funcします*this)。試す:

std::function<void(int)> testFunc = std::bind(&A::func, this);

(注意してstd::bind(&A::func, *this)std::bind(&A::func, this)セマンティクスが少し異なります。)

于 2012-04-05T05:16:29.710 に答える