使用C ++ lambda指向成员函数的指针

时间:2019-05-28 09:59:29

标签: c++ lambda callback member

我正在尝试找到一种在不同类实例之间提供指向成员函数的指针的方法。目前,我能够提供不带参数的成员函数的指针,但是当指向的函数具有参数时,就无法做到这一点。

示例代码来说明我的问题:

#include <iostream>

class Event
{
public:
    std::string type;
    Event(std::string type):type(type){}
};

class EventDispatcherBase
{
public:

    void addEventListener(std::function<void(Event &event)> listener)
    {
        Event myEvent("Type of the myEvent object");
        listener(myEvent);
    }
};

class EventDispatcherClass:public EventDispatcherBase
{
public:
    EventDispatcherClass()
    {
        addEventListener([](Event &event){std::cout << event.type << std::endl;});
        //addEventListener([this]{listener(Event event);});
    };

    void listener(Event &event)
    {
        std::cout << event.type << std::endl;
    }
};

int main()
{
    EventDispatcherClass eventDispatcherClass;

    return 0;
}

此代码与匿名lambda表达式一起使用,并在控制台中输出“ myEvent对象的类型”。但是,如果我取消注释该行

addEventListener([this]{listener(Event event);});

在EventDispatcherClass的构造函数中,为了传递指向void listener(Event &event)成员函数的指针,编译器将引发以下错误:

  

从'(在... / main.cpp:27:26)处的lambda没有可行的转换   'std :: function'

我不明白为什么?

如果有人可以帮助我,我先感谢他/她。

3 个答案:

答案 0 :(得分:4)

  

但是当指向的函数具有参数时,则无法做到这一点。

lambda应该采用Event&类型的参数,该参数将转发到lambda内部的成员函数。因此将其更改为

addEventListener([this](Event &event){listener(event);});
//                     ^^^^^^^^^^^^^^

LIVE

答案 1 :(得分:3)

工作线:

addEventListener([](Event &event){std::cout << event.type << std::endl;});

看起来不像破碎的东西:

//addEventListener([this]{listener(Event event);});

因此,先一点一点地更改 working 行。

  1. 添加您想要的捕获表达式,它仍然有效

    addEventListener([this](Event &event){std::cout << event.type << std::endl;});
    
  2. 将主体更改为所需的主体,它仍然有效

    addEventListener([this](Event &event){ this->listener(event); });
    

如果您在查看两个版本之间有什么区别时遇到麻烦-当您自己编写它们时实际上很常见,并且看到的是打算键入的内容而不是那里的内容-请尝试更改布局以将所有内容对齐(这样您会看到丢失的(Event &event)),或者如上所述将其逐步转换为另一种,或者仅用另一种替换并比较文件版本。< / p>

答案 2 :(得分:0)

只需将其更改为addEventListener(listener);

,并将函数本身设为static void listener(Event &event)