【问题标题】:Member function callback成员函数回调
【发布时间】:2013-08-20 23:57:58
【问题描述】:

Present 是一个将函数注册为回调的类。

class Action {
private:
    static std::multimap<std::string, std::function<void()>> actions;
public:
    static void registerAction(const std::string &key, std::function<void()> action);
}

显然它不能注册成员函数,因为指向成员函数的函数指针对象需要指定类,但每个类都应该能够注册它们的函数。 std::function&lt;void(Class&amp;)&gt;

使用模板系统,我无法从我想的静态类的一个“实例”访问所有操作。这怎么可能实现?

示例如下:

class B {
public:
    B() {
        Action::registerAction("some_action", &callMe);
    }

    void callMe(){}
}

【问题讨论】:

    标签: c++ c++11 callback function-pointers


    【解决方案1】:

    鉴于成员函数采用了附加参数,您需要绑定此参数。例如,您可以使用如下内容:

    Action::registerAction("come_action", std::bind(&callMe, this));
    

    bind() 表达式将创建一个不带参数的函数对象。显然,要使这种方法发挥作用,this 需要坚持足够长的时间。

    【讨论】:

    • 只是问:这样做安全吗:Action::registerAction(..., reinterpret_cast&lt;void (*)()&gt;(&amp;callMe));
    • @0x499602D2:只是回答:没有。除了不安全之外,它也行不通。
    • @0x499602D2:尝试调用该函数并使用对象的成员(如果您不需要使用成员,则可以将函数设为static,并且不需要使用一个演员)。您设法生成指针的事实没有显示任何内容。
    • @0x499602D2:为了完整起见,相关部分是5.2.10 [expr.reinterpret.cast]第6段,第二句:“通过指向函数类型的指针调用函数的效果( 8.3.5) 与函数定义中使用的类型不同的是未定义的。”
    【解决方案2】:

    您可以使用 std::bind 或 lambda 函数

    // std::bind
    Action::registerAction( "bla", std::bind(&callMe, this) );
    
    // lambda
    Action::registerAction( "bla", [this]() { this->callMe(); } );
    

    我建议阅读 lambda 函数。非常易于使用,并且比 std::bind 更强大。

    【讨论】:

    • 而且它们通常更容易被编译器内联,尽管在这种情况下它应该无关紧要。
    猜你喜欢
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多