std::具有非静态成员函数的函数

std::function with non-static member functions

本文关键字:函数 静态成员 std      更新时间:2023-10-16

我试图理解一个概念和一个错误。这个怎么了?

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::函数,比如so:

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);
};

如果有人能解释这些巨大的神秘错误意味着什么以及如何修复它们,我将不胜感激

我认为您遇到的问题是,成员函数不仅需要一个函数指针,还需要一个指向调用对象的指针。换句话说,成员函数有一个附加的隐式参数,它是指向调用对象的指针。

要将成员函数设置为std::函数,需要使用std::bind,如下所示:

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

这将当前A实例的This指针绑定到函数,因此它具有函数指针和对象实例,这些信息足以正确调用函数。_1参数表示在调用函数时将提供第一个显式参数。

使用c++11,您还可以使用比std::bind:更容易读取的lambda

index[WM_CREATE] = [this](HWND h, UINT u, WPARAM w, LPARAM l)
{
  create(h, u, w, l);
}

我的问题是,是否可以创建任何类型的对象来调用特定实例的成员

在这种情况下,唯一缺少的信息实际上是std::function对象应该使用哪个特定实例:&A::func不能单独使用(例如(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)的语义略有不同。)